Merge changes I98927540,I95c71e8d into jb-mr2-dev
* changes: Fix dump when virtual display exists Isolate knowledge that fb target == output buffer
This commit is contained in:
commit
78d2a07f7a
@ -235,8 +235,7 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const {
|
|||||||
|
|
||||||
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
|
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
sp<Fence> fence = hwc.getAndResetReleaseFence(mType);
|
mDisplaySurface->onFrameCommitted();
|
||||||
mDisplaySurface->onFrameCommitted(fence);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,10 +49,9 @@ public:
|
|||||||
virtual status_t advanceFrame() = 0;
|
virtual status_t advanceFrame() = 0;
|
||||||
|
|
||||||
// onFrameCommitted is called after the frame has been committed to the
|
// onFrameCommitted is called after the frame has been committed to the
|
||||||
// hardware composer and a release fence is available for the buffer.
|
// hardware composer. The surface collects the release fence for this
|
||||||
// Further operations on the buffer can be queued as long as they wait for
|
// frame's buffer.
|
||||||
// the fence to signal.
|
virtual void onFrameCommitted() = 0;
|
||||||
virtual void onFrameCommitted(const sp<Fence>& fence) = 0;
|
|
||||||
|
|
||||||
virtual void dump(String8& result) const = 0;
|
virtual void dump(String8& result) const = 0;
|
||||||
|
|
||||||
|
@ -140,7 +140,8 @@ void FramebufferSurface::freeBufferLocked(int slotIndex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferSurface::onFrameCommitted(const sp<Fence>& fence) {
|
void FramebufferSurface::onFrameCommitted() {
|
||||||
|
sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
|
||||||
if (fence->isValid() &&
|
if (fence->isValid() &&
|
||||||
mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
|
mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
|
||||||
status_t err = addReleaseFence(mCurrentBufferSlot, fence);
|
status_t err = addReleaseFence(mCurrentBufferSlot, fence);
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
|
|
||||||
virtual status_t compositionComplete();
|
virtual status_t compositionComplete();
|
||||||
virtual status_t advanceFrame();
|
virtual status_t advanceFrame();
|
||||||
virtual void onFrameCommitted(const sp<Fence>& fence);
|
virtual void onFrameCommitted();
|
||||||
|
|
||||||
// Implementation of DisplaySurface::dump(). Note that ConsumerBase also
|
// Implementation of DisplaySurface::dump(). Note that ConsumerBase also
|
||||||
// has a non-virtual dump() with the same signature.
|
// has a non-virtual dump() with the same signature.
|
||||||
|
@ -657,15 +657,12 @@ status_t HWComposer::commit() {
|
|||||||
mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
|
mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For virtual displays, the framebufferTarget buffer also serves as
|
|
||||||
// the HWC output buffer, so we need to copy the buffer handle and
|
|
||||||
// dup() the acquire fence.
|
|
||||||
for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
|
for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
|
||||||
DisplayData& disp(mDisplayData[i]);
|
DisplayData& disp(mDisplayData[i]);
|
||||||
if (disp.framebufferTarget) {
|
if (disp.outbufHandle) {
|
||||||
mLists[i]->outbuf = disp.framebufferTarget->handle;
|
mLists[i]->outbuf = disp.outbufHandle;
|
||||||
mLists[i]->outbufAcquireFenceFd =
|
mLists[i]->outbufAcquireFenceFd =
|
||||||
dup(disp.framebufferTarget->acquireFenceFd);
|
disp.outbufAcquireFence->dup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,17 +703,15 @@ status_t HWComposer::acquire(int disp) {
|
|||||||
|
|
||||||
void HWComposer::disconnectDisplay(int disp) {
|
void HWComposer::disconnectDisplay(int disp) {
|
||||||
LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
|
LOG_ALWAYS_FATAL_IF(disp < 0 || disp == HWC_DISPLAY_PRIMARY);
|
||||||
if (disp >= HWC_NUM_DISPLAY_TYPES) {
|
|
||||||
// nothing to do for these yet
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DisplayData& dd(mDisplayData[disp]);
|
DisplayData& dd(mDisplayData[disp]);
|
||||||
if (dd.list != NULL) {
|
|
||||||
free(dd.list);
|
free(dd.list);
|
||||||
dd.list = NULL;
|
dd.list = NULL;
|
||||||
dd.framebufferTarget = NULL; // points into dd.list
|
dd.framebufferTarget = NULL; // points into dd.list
|
||||||
dd.fbTargetHandle = NULL;
|
dd.fbTargetHandle = NULL;
|
||||||
}
|
dd.outbufHandle = NULL;
|
||||||
|
dd.lastRetireFence = Fence::NO_FENCE;
|
||||||
|
dd.lastDisplayFence = Fence::NO_FENCE;
|
||||||
|
dd.outbufAcquireFence = Fence::NO_FENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int HWComposer::getVisualID() const {
|
int HWComposer::getVisualID() const {
|
||||||
@ -765,6 +760,25 @@ void HWComposer::fbDump(String8& result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t HWComposer::setOutputBuffer(int32_t id, const sp<Fence>& acquireFence,
|
||||||
|
const sp<GraphicBuffer>& buf) {
|
||||||
|
if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
|
||||||
|
return BAD_INDEX;
|
||||||
|
if (id < VIRTUAL_DISPLAY_ID_BASE)
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
|
||||||
|
DisplayData& disp(mDisplayData[id]);
|
||||||
|
disp.outbufHandle = buf->handle;
|
||||||
|
disp.outbufAcquireFence = acquireFence;
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp<Fence> HWComposer::getLastRetireFence(int32_t id) {
|
||||||
|
if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
|
||||||
|
return Fence::NO_FENCE;
|
||||||
|
return mDisplayData[id].lastRetireFence;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper template to implement a concrete HWCLayer
|
* Helper template to implement a concrete HWCLayer
|
||||||
* This holds the pointer to the concrete hwc layer type
|
* This holds the pointer to the concrete hwc layer type
|
||||||
@ -1071,6 +1085,7 @@ HWComposer::DisplayData::DisplayData()
|
|||||||
capacity(0), list(NULL),
|
capacity(0), list(NULL),
|
||||||
framebufferTarget(NULL), fbTargetHandle(0),
|
framebufferTarget(NULL), fbTargetHandle(0),
|
||||||
lastRetireFence(Fence::NO_FENCE), lastDisplayFence(Fence::NO_FENCE),
|
lastRetireFence(Fence::NO_FENCE), lastDisplayFence(Fence::NO_FENCE),
|
||||||
|
outbufHandle(NULL), outbufAcquireFence(Fence::NO_FENCE),
|
||||||
events(0)
|
events(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -128,6 +128,17 @@ public:
|
|||||||
int fbCompositionComplete();
|
int fbCompositionComplete();
|
||||||
void fbDump(String8& result);
|
void fbDump(String8& result);
|
||||||
|
|
||||||
|
// Set the output buffer and acquire fence for a virtual display.
|
||||||
|
// Returns INVALID_OPERATION if id is not a virtual display.
|
||||||
|
status_t setOutputBuffer(int32_t id, const sp<Fence>& acquireFence,
|
||||||
|
const sp<GraphicBuffer>& buf);
|
||||||
|
|
||||||
|
// Get the retire fence for the last committed frame. This fence will
|
||||||
|
// signal when the h/w composer is completely finished with the frame.
|
||||||
|
// For physical displays, it is no longer being displayed. For virtual
|
||||||
|
// displays, writes to the output buffer are complete.
|
||||||
|
sp<Fence> getLastRetireFence(int32_t id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interface to hardware composer's layers functionality.
|
* Interface to hardware composer's layers functionality.
|
||||||
* This abstracts the HAL interface to layers which can evolve in
|
* This abstracts the HAL interface to layers which can evolve in
|
||||||
@ -306,6 +317,8 @@ private:
|
|||||||
sp<Fence> lastRetireFence; // signals when the last set op retires
|
sp<Fence> lastRetireFence; // signals when the last set op retires
|
||||||
sp<Fence> lastDisplayFence; // signals when the last set op takes
|
sp<Fence> lastDisplayFence; // signals when the last set op takes
|
||||||
// effect on screen
|
// effect on screen
|
||||||
|
buffer_handle_t outbufHandle;
|
||||||
|
sp<Fence> outbufAcquireFence;
|
||||||
|
|
||||||
// protected by mEventControlLock
|
// protected by mEventControlLock
|
||||||
int32_t events;
|
int32_t events;
|
||||||
|
@ -70,9 +70,21 @@ status_t VirtualDisplaySurface::advanceFrame() {
|
|||||||
return mHwc.fbPost(mDisplayId, fence, mAcquiredBuffer);
|
return mHwc.fbPost(mDisplayId, fence, mAcquiredBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualDisplaySurface::onFrameCommitted(const sp<Fence>& fence) {
|
void VirtualDisplaySurface::onFrameCommitted() {
|
||||||
Mutex::Autolock lock(mMutex);
|
Mutex::Autolock lock(mMutex);
|
||||||
if (mAcquiredBuffer != NULL) {
|
if (mAcquiredBuffer != NULL) {
|
||||||
|
// fbFence signals when reads from the framebuffer are finished
|
||||||
|
// outFence signals when writes to the output buffer are finished
|
||||||
|
// It's unlikely that there will be an implementation where fbFence
|
||||||
|
// signals after outFence (in fact they'll typically be the same
|
||||||
|
// sync_pt), but just to be pedantic we merge them so the sink will
|
||||||
|
// be sure to wait until both are complete.
|
||||||
|
sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId);
|
||||||
|
sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
|
||||||
|
sp<Fence> fence = Fence::merge(
|
||||||
|
String8::format("HWC done: %.21s", mName.string()),
|
||||||
|
fbFence, outFence);
|
||||||
|
|
||||||
status_t result = mSource->releaseBuffer(fence);
|
status_t result = mSource->releaseBuffer(fence);
|
||||||
ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": "
|
ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": "
|
||||||
"failed to release buffer: %d", mName.string(), result);
|
"failed to release buffer: %d", mName.string(), result);
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
|
|
||||||
virtual status_t compositionComplete();
|
virtual status_t compositionComplete();
|
||||||
virtual status_t advanceFrame();
|
virtual status_t advanceFrame();
|
||||||
virtual void onFrameCommitted(const sp<Fence>& fence);
|
virtual void onFrameCommitted();
|
||||||
virtual void dump(String8& result) const;
|
virtual void dump(String8& result) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2381,9 +2381,21 @@ void SurfaceFlinger::dumpAllLocked(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Vector< sp<Layer> >&
|
const Vector< sp<Layer> >&
|
||||||
SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) {
|
SurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
|
||||||
// Note: mStateLock is held here
|
// Note: mStateLock is held here
|
||||||
return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ();
|
wp<IBinder> dpy;
|
||||||
|
for (size_t i=0 ; i<mDisplays.size() ; i++) {
|
||||||
|
if (mDisplays.valueAt(i)->getHwcDisplayId() == id) {
|
||||||
|
dpy = mDisplays.keyAt(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dpy == NULL) {
|
||||||
|
ALOGE("getLayerSortedByZForHwcDisplay: invalid hwc display id %d", id);
|
||||||
|
// Just use the primary display so we have something to return
|
||||||
|
dpy = getBuiltInDisplay(DisplayDevice::DISPLAY_PRIMARY);
|
||||||
|
}
|
||||||
|
return getDisplayDevice(dpy)->getVisibleLayersSortedByZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SurfaceFlinger::startDdmConnection()
|
bool SurfaceFlinger::startDdmConnection()
|
||||||
|
@ -122,7 +122,7 @@ public:
|
|||||||
|
|
||||||
// for debugging only
|
// for debugging only
|
||||||
// TODO: this should be made accessible only to HWComposer
|
// TODO: this should be made accessible only to HWComposer
|
||||||
const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int disp);
|
const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Client;
|
friend class Client;
|
||||||
|
Loading…
Reference in New Issue
Block a user