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 {
|
||||
if (hwc.initCheck() == NO_ERROR) {
|
||||
sp<Fence> fence = hwc.getAndResetReleaseFence(mType);
|
||||
mDisplaySurface->onFrameCommitted(fence);
|
||||
mDisplaySurface->onFrameCommitted();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
{}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user