am 78d2a07f: Merge changes I98927540,I95c71e8d into jb-mr2-dev

* commit '78d2a07f7aa598ce724664b1819db073eb0706ae':
  Fix dump when virtual display exists
  Isolate knowledge that fb target == output buffer
This commit is contained in:
Jesse Hall 2013-03-25 22:38:59 +00:00 committed by Android Git Automerger
commit 8d7fab0365
10 changed files with 80 additions and 29 deletions

View File

@ -235,8 +235,7 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const {
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
if (hwc.initCheck() == NO_ERROR) {
sp<Fence> fence = hwc.getAndResetReleaseFence(mType);
mDisplaySurface->onFrameCommitted(fence);
mDisplaySurface->onFrameCommitted();
}
}

View File

@ -49,10 +49,9 @@ public:
virtual status_t advanceFrame() = 0;
// onFrameCommitted is called after the frame has been committed to the
// hardware composer and a release fence is available for the buffer.
// Further operations on the buffer can be queued as long as they wait for
// the fence to signal.
virtual void onFrameCommitted(const sp<Fence>& fence) = 0;
// hardware composer. The surface collects the release fence for this
// frame's buffer.
virtual void onFrameCommitted() = 0;
virtual void dump(String8& result) const = 0;

View File

@ -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() &&
mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
status_t err = addReleaseFence(mCurrentBufferSlot, fence);

View File

@ -43,7 +43,7 @@ public:
virtual status_t compositionComplete();
virtual status_t advanceFrame();
virtual void onFrameCommitted(const sp<Fence>& fence);
virtual void onFrameCommitted();
// Implementation of DisplaySurface::dump(). Note that ConsumerBase also
// has a non-virtual dump() with the same signature.

View File

@ -657,15 +657,12 @@ status_t HWComposer::commit() {
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++) {
DisplayData& disp(mDisplayData[i]);
if (disp.framebufferTarget) {
mLists[i]->outbuf = disp.framebufferTarget->handle;
if (disp.outbufHandle) {
mLists[i]->outbuf = disp.outbufHandle;
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) {
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]);
if (dd.list != NULL) {
free(dd.list);
dd.list = NULL;
dd.framebufferTarget = NULL; // points into dd.list
dd.fbTargetHandle = NULL;
}
free(dd.list);
dd.list = NULL;
dd.framebufferTarget = NULL; // points into dd.list
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 {
@ -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
* This holds the pointer to the concrete hwc layer type
@ -1071,6 +1085,7 @@ HWComposer::DisplayData::DisplayData()
capacity(0), list(NULL),
framebufferTarget(NULL), fbTargetHandle(0),
lastRetireFence(Fence::NO_FENCE), lastDisplayFence(Fence::NO_FENCE),
outbufHandle(NULL), outbufAcquireFence(Fence::NO_FENCE),
events(0)
{}

View File

@ -128,6 +128,17 @@ public:
int fbCompositionComplete();
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.
* 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> lastDisplayFence; // signals when the last set op takes
// effect on screen
buffer_handle_t outbufHandle;
sp<Fence> outbufAcquireFence;
// protected by mEventControlLock
int32_t events;

View File

@ -70,9 +70,21 @@ status_t VirtualDisplaySurface::advanceFrame() {
return mHwc.fbPost(mDisplayId, fence, mAcquiredBuffer);
}
void VirtualDisplaySurface::onFrameCommitted(const sp<Fence>& fence) {
void VirtualDisplaySurface::onFrameCommitted() {
Mutex::Autolock lock(mMutex);
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);
ALOGE_IF(result != NO_ERROR, "VirtualDisplaySurface \"%s\": "
"failed to release buffer: %d", mName.string(), result);

View File

@ -58,7 +58,7 @@ public:
virtual status_t compositionComplete();
virtual status_t advanceFrame();
virtual void onFrameCommitted(const sp<Fence>& fence);
virtual void onFrameCommitted();
virtual void dump(String8& result) const;
private:

View File

@ -2381,9 +2381,21 @@ void SurfaceFlinger::dumpAllLocked(
}
const Vector< sp<Layer> >&
SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) {
SurfaceFlinger::getLayerSortedByZForHwcDisplay(int id) {
// 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()

View File

@ -122,7 +122,7 @@ public:
// for debugging only
// TODO: this should be made accessible only to HWComposer
const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int disp);
const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
private:
friend class Client;