Loading services/surfaceflinger/DisplayHardware.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,14 @@ void DisplayHardware::dump(String8& res) const } } void DisplayHardware::makeCurrent(const DisplayHardware& hw, EGLContext ctx) { EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); if (sur != hw.mSurface) { EGLDisplay dpy = eglGetCurrentDisplay(); eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); } } // ---------------------------------------------------------------------------- void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { Loading services/surfaceflinger/DisplayHardware.h +2 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ public: } inline Rect bounds() const { return getBounds(); } static void makeCurrent(const DisplayHardware& hw, EGLContext ctx); private: void init(EGLConfig config); Loading services/surfaceflinger/Layer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -294,7 +294,7 @@ void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) { int fenceFd = -1; if (mNeedHwcFence) { if (mNeedHwcFence && (layer.getCompositionType() == HWC_OVERLAY)) { sp<Fence> fence = mSurfaceTexture->getCurrentFence(); if (fence.get()) { fenceFd = fence->dup(); Loading services/surfaceflinger/SurfaceFlinger.cpp +96 −117 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ SurfaceFlinger::SurfaceFlinger() mTransactionFlags(0), mTransationPending(false), mLayersRemoved(false), mRepaintEverything(0), mBootTime(systemTime()), mVisibleRegionsDirty(false), mHwWorkListDirty(false), Loading Loading @@ -577,7 +578,7 @@ void SurfaceFlinger::handleMessageInvalidate() { void SurfaceFlinger::handleMessageRefresh() { handleRefresh(); if (mVisibleRegionsDirty) { if (CC_UNLIKELY(mVisibleRegionsDirty)) { mVisibleRegionsDirty = false; invalidateHwcGeometry(); Loading @@ -586,9 +587,8 @@ void SurfaceFlinger::handleMessageRefresh() { */ const LayerVector& currentLayers(mDrawingState.layersSortedByZ); // TODO: iterate through all displays { DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); Region opaqueRegion; Region dirtyRegion; Loading @@ -612,45 +612,70 @@ void SurfaceFlinger::handleMessageRefresh() { } } const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); HWComposer& hwc(getHwComposer()); if (hwc.initCheck() == NO_ERROR) { // build the h/w work list const bool workListsDirty = mHwWorkListDirty; mHwWorkListDirty = false; for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); // TODO: iterate through all displays for (int dpy=0 ; dpy<1 ; dpy++) { DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); if (hw.dirtyRegion.isEmpty()) { continue; hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { const sp<LayerBase>& layer(currentLayers[i]); if (CC_UNLIKELY(workListsDirty)) { layer->setGeometry(hw, *cur); if (mDebugDisableHWC || mDebugRegion) { cur->setSkip(true); } } /* * update the per-frame h/w composer data for each layer * and build the transparent region of the FB */ layer->setPerFrameData(*cur); } } status_t err = hwc.prepare(); ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); } const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); // transform the dirty region into this screen's coordinate space const Transform& planeTransform(hw.getTransform()); Region dirtyRegion; if (repaintEverything) { dirtyRegion.set(hw.bounds()); } else { dirtyRegion = planeTransform.transform(hw.dirtyRegion); dirtyRegion.andSelf(hw.bounds()); } else { dirtyRegion.set(hw.bounds()); } hw.dirtyRegion.clear(); // build the h/w work list if (CC_UNLIKELY(mHwWorkListDirty)) { handleWorkList(hw); } if (CC_LIKELY(hw.canDraw())) { if (!dirtyRegion.isEmpty()) { if (hw.canDraw()) { // repaint the framebuffer (if needed) handleRepaint(hw, dirtyRegion); } } // inform the h/w that we're done compositing hw.compositionComplete(); postFramebuffer(); } else { // pretend we did the post hw.compositionComplete(); } } postFramebuffer(); #if 0 #if 1 // render to the external display if we have one EGLSurface externalDisplaySurface = getExternalDisplaySurface(); if (externalDisplaySurface != EGL_NO_SURFACE) { Loading @@ -670,6 +695,7 @@ void SurfaceFlinger::handleMessageRefresh() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); DisplayHardware& hw(const_cast<DisplayDevice&>(getDisplayHardware(0))); const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { Loading @@ -695,47 +721,53 @@ void SurfaceFlinger::handleMessageRefresh() { void SurfaceFlinger::postFramebuffer() { ATRACE_CALL(); // mSwapRegion can be empty here is some cases, for instance if a hidden // or fully transparent window is updating. // in that case, we need to flip anyways to not risk a deadlock with // h/w composer. const DisplayHardware& hw(getDefaultDisplayHardware()); HWComposer& hwc(getHwComposer()); const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); size_t numLayers = layers.size(); const nsecs_t now = systemTime(); mDebugInSwapBuffers = now; HWComposer& hwc(getHwComposer()); for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); if (hwc.initCheck() == NO_ERROR) { const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { if (cur->getCompositionType() == HWC_OVERLAY) { layers[i]->setAcquireFence(*cur); } else { cur->setAcquireFenceFd(-1); } for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { const sp<LayerBase>& layer(currentLayers[i]); layer->setAcquireFence(*cur); } } hw.flip(hw.swapRegion); hw.swapRegion.clear(); } if (hwc.initCheck() == NO_ERROR) { // FIXME: eventually commit() won't take arguments hwc.commit(mEGLDisplay, getDefaultDisplayHardware().getEGLSurface()); } for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); if (hwc.initCheck() == NO_ERROR) { hwc.commit(mEGLDisplay, hw.getEGLSurface()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { layers[i]->onLayerDisplayed(&*cur); for (size_t i = 0; cur != end && i < count; ++i, ++cur) { currentLayers[i]->onLayerDisplayed(&*cur); } } else { eglSwapBuffers(mEGLDisplay, hw.getEGLSurface()); for (size_t i = 0; i < numLayers; i++) { layers[i]->onLayerDisplayed(NULL); for (size_t i = 0; i < count; i++) { currentLayers[i]->onLayerDisplayed(NULL); } } // FIXME: we need to call eglSwapBuffers() on displays that have GL composition } mLastSwapBufferTime = systemTime() - now; mDebugInSwapBuffers = 0; } Loading Loading @@ -1028,27 +1060,6 @@ void SurfaceFlinger::handleRefresh() } } void SurfaceFlinger::handleWorkList(const DisplayHardware& hw) { mHwWorkListDirty = false; HWComposer& hwc(getHwComposer()); if (hwc.initCheck() == NO_ERROR) { const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); hwc.createWorkList(count); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { currentLayers[i]->setGeometry(hw, *cur); if (mDebugDisableHWC || mDebugRegion) { cur->setSkip(true); } } } } void SurfaceFlinger::handleRepaint(const DisplayHardware& hw, const Region& inDirtyRegion) { Loading @@ -1063,10 +1074,6 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw, debugFlashRegions(hw, dirtyRegion); } // set the frame buffer glMatrixMode(GL_MODELVIEW); glLoadIdentity(); uint32_t flags = hw.getFlags(); if (flags & DisplayHardware::SWAP_RECTANGLE) { // we can redraw only what's dirty, but since SWAP_RECTANGLE only Loading @@ -1087,57 +1094,29 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw, } } setupHardwareComposer(hw); composeSurfaces(hw, dirtyRegion); // update the swap region and clear the dirty region hw.swapRegion.orSelf(dirtyRegion); } void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) { HWComposer& hwc(getHwComposer()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); if (cur == end) { return; } const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); size_t count = layers.size(); ALOGE_IF(hwc.getNumLayers() != count, "HAL number of layers (%d) doesn't match surfaceflinger (%d)", hwc.getNumLayers(), count); // just to be extra-safe, use the smallest count if (hwc.initCheck() == NO_ERROR) { count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); } const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); // FIXME: this should be per display if (cur==end || fbLayerCount) { /* * update the per-frame h/w composer data for each layer * and build the transparent region of the FB */ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { const sp<LayerBase>& layer(layers[i]); layer->setPerFrameData(*cur); } status_t err = hwc.prepare(); ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); } DisplayHardware::makeCurrent(hw, mEGLContext); void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) { HWComposer& hwc(getHwComposer()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); // set the frame buffer glMatrixMode(GL_MODELVIEW); glLoadIdentity(); const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); if (cur==end || fbLayerCount) { // Never touch the framebuffer if we don't have any framebuffer layers if (hwc.getLayerCount(HWC_OVERLAY)) { if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display // when using overlays, we assume a fully transparent framebuffer // NOTE: we could reduce how much we need to clear, for instance // remove where there are opaque FB layers. however, on some Loading services/surfaceflinger/SurfaceFlinger.h +0 −2 Original line number Diff line number Diff line Loading @@ -237,7 +237,6 @@ private: void handlePageFlip(); void handleRefresh(); void handleWorkList(const DisplayHardware& hw); void handleRepaint(const DisplayHardware& hw, const Region& dirtyRegion); /* ------------------------------------------------------------------------ Loading Loading @@ -339,7 +338,6 @@ private: uint32_t layerStack, Region& dirtyRegion, Region& opaqueRegion); void postFramebuffer(); void setupHardwareComposer(const DisplayHardware& hw); void composeSurfaces(const DisplayHardware& hw, const Region& dirty); void drawWormhole(const Region& region) const; GLuint getProtectedTexName() const { Loading Loading
services/surfaceflinger/DisplayHardware.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -310,6 +310,14 @@ void DisplayHardware::dump(String8& res) const } } void DisplayHardware::makeCurrent(const DisplayHardware& hw, EGLContext ctx) { EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); if (sur != hw.mSurface) { EGLDisplay dpy = eglGetCurrentDisplay(); eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); } } // ---------------------------------------------------------------------------- void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { Loading
services/surfaceflinger/DisplayHardware.h +2 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,8 @@ public: } inline Rect bounds() const { return getBounds(); } static void makeCurrent(const DisplayHardware& hw, EGLContext ctx); private: void init(EGLConfig config); Loading
services/surfaceflinger/Layer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -294,7 +294,7 @@ void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) { int fenceFd = -1; if (mNeedHwcFence) { if (mNeedHwcFence && (layer.getCompositionType() == HWC_OVERLAY)) { sp<Fence> fence = mSurfaceTexture->getCurrentFence(); if (fence.get()) { fenceFd = fence->dup(); Loading
services/surfaceflinger/SurfaceFlinger.cpp +96 −117 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ SurfaceFlinger::SurfaceFlinger() mTransactionFlags(0), mTransationPending(false), mLayersRemoved(false), mRepaintEverything(0), mBootTime(systemTime()), mVisibleRegionsDirty(false), mHwWorkListDirty(false), Loading Loading @@ -577,7 +578,7 @@ void SurfaceFlinger::handleMessageInvalidate() { void SurfaceFlinger::handleMessageRefresh() { handleRefresh(); if (mVisibleRegionsDirty) { if (CC_UNLIKELY(mVisibleRegionsDirty)) { mVisibleRegionsDirty = false; invalidateHwcGeometry(); Loading @@ -586,9 +587,8 @@ void SurfaceFlinger::handleMessageRefresh() { */ const LayerVector& currentLayers(mDrawingState.layersSortedByZ); // TODO: iterate through all displays { DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); Region opaqueRegion; Region dirtyRegion; Loading @@ -612,45 +612,70 @@ void SurfaceFlinger::handleMessageRefresh() { } } const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); HWComposer& hwc(getHwComposer()); if (hwc.initCheck() == NO_ERROR) { // build the h/w work list const bool workListsDirty = mHwWorkListDirty; mHwWorkListDirty = false; for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); // TODO: iterate through all displays for (int dpy=0 ; dpy<1 ; dpy++) { DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); if (hw.dirtyRegion.isEmpty()) { continue; hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { const sp<LayerBase>& layer(currentLayers[i]); if (CC_UNLIKELY(workListsDirty)) { layer->setGeometry(hw, *cur); if (mDebugDisableHWC || mDebugRegion) { cur->setSkip(true); } } /* * update the per-frame h/w composer data for each layer * and build the transparent region of the FB */ layer->setPerFrameData(*cur); } } status_t err = hwc.prepare(); ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); } const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); // transform the dirty region into this screen's coordinate space const Transform& planeTransform(hw.getTransform()); Region dirtyRegion; if (repaintEverything) { dirtyRegion.set(hw.bounds()); } else { dirtyRegion = planeTransform.transform(hw.dirtyRegion); dirtyRegion.andSelf(hw.bounds()); } else { dirtyRegion.set(hw.bounds()); } hw.dirtyRegion.clear(); // build the h/w work list if (CC_UNLIKELY(mHwWorkListDirty)) { handleWorkList(hw); } if (CC_LIKELY(hw.canDraw())) { if (!dirtyRegion.isEmpty()) { if (hw.canDraw()) { // repaint the framebuffer (if needed) handleRepaint(hw, dirtyRegion); } } // inform the h/w that we're done compositing hw.compositionComplete(); postFramebuffer(); } else { // pretend we did the post hw.compositionComplete(); } } postFramebuffer(); #if 0 #if 1 // render to the external display if we have one EGLSurface externalDisplaySurface = getExternalDisplaySurface(); if (externalDisplaySurface != EGL_NO_SURFACE) { Loading @@ -670,6 +695,7 @@ void SurfaceFlinger::handleMessageRefresh() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); DisplayHardware& hw(const_cast<DisplayDevice&>(getDisplayHardware(0))); const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { Loading @@ -695,47 +721,53 @@ void SurfaceFlinger::handleMessageRefresh() { void SurfaceFlinger::postFramebuffer() { ATRACE_CALL(); // mSwapRegion can be empty here is some cases, for instance if a hidden // or fully transparent window is updating. // in that case, we need to flip anyways to not risk a deadlock with // h/w composer. const DisplayHardware& hw(getDefaultDisplayHardware()); HWComposer& hwc(getHwComposer()); const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); size_t numLayers = layers.size(); const nsecs_t now = systemTime(); mDebugInSwapBuffers = now; HWComposer& hwc(getHwComposer()); for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); if (hwc.initCheck() == NO_ERROR) { const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { if (cur->getCompositionType() == HWC_OVERLAY) { layers[i]->setAcquireFence(*cur); } else { cur->setAcquireFenceFd(-1); } for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { const sp<LayerBase>& layer(currentLayers[i]); layer->setAcquireFence(*cur); } } hw.flip(hw.swapRegion); hw.swapRegion.clear(); } if (hwc.initCheck() == NO_ERROR) { // FIXME: eventually commit() won't take arguments hwc.commit(mEGLDisplay, getDefaultDisplayHardware().getEGLSurface()); } for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy))); const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); if (hwc.initCheck() == NO_ERROR) { hwc.commit(mEGLDisplay, hw.getEGLSurface()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { layers[i]->onLayerDisplayed(&*cur); for (size_t i = 0; cur != end && i < count; ++i, ++cur) { currentLayers[i]->onLayerDisplayed(&*cur); } } else { eglSwapBuffers(mEGLDisplay, hw.getEGLSurface()); for (size_t i = 0; i < numLayers; i++) { layers[i]->onLayerDisplayed(NULL); for (size_t i = 0; i < count; i++) { currentLayers[i]->onLayerDisplayed(NULL); } } // FIXME: we need to call eglSwapBuffers() on displays that have GL composition } mLastSwapBufferTime = systemTime() - now; mDebugInSwapBuffers = 0; } Loading Loading @@ -1028,27 +1060,6 @@ void SurfaceFlinger::handleRefresh() } } void SurfaceFlinger::handleWorkList(const DisplayHardware& hw) { mHwWorkListDirty = false; HWComposer& hwc(getHwComposer()); if (hwc.initCheck() == NO_ERROR) { const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); hwc.createWorkList(count); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { currentLayers[i]->setGeometry(hw, *cur); if (mDebugDisableHWC || mDebugRegion) { cur->setSkip(true); } } } } void SurfaceFlinger::handleRepaint(const DisplayHardware& hw, const Region& inDirtyRegion) { Loading @@ -1063,10 +1074,6 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw, debugFlashRegions(hw, dirtyRegion); } // set the frame buffer glMatrixMode(GL_MODELVIEW); glLoadIdentity(); uint32_t flags = hw.getFlags(); if (flags & DisplayHardware::SWAP_RECTANGLE) { // we can redraw only what's dirty, but since SWAP_RECTANGLE only Loading @@ -1087,57 +1094,29 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw, } } setupHardwareComposer(hw); composeSurfaces(hw, dirtyRegion); // update the swap region and clear the dirty region hw.swapRegion.orSelf(dirtyRegion); } void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) { HWComposer& hwc(getHwComposer()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); if (cur == end) { return; } const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); size_t count = layers.size(); ALOGE_IF(hwc.getNumLayers() != count, "HAL number of layers (%d) doesn't match surfaceflinger (%d)", hwc.getNumLayers(), count); // just to be extra-safe, use the smallest count if (hwc.initCheck() == NO_ERROR) { count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); } const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); // FIXME: this should be per display if (cur==end || fbLayerCount) { /* * update the per-frame h/w composer data for each layer * and build the transparent region of the FB */ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { const sp<LayerBase>& layer(layers[i]); layer->setPerFrameData(*cur); } status_t err = hwc.prepare(); ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); } DisplayHardware::makeCurrent(hw, mEGLContext); void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty) { HWComposer& hwc(getHwComposer()); HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); // set the frame buffer glMatrixMode(GL_MODELVIEW); glLoadIdentity(); const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); if (cur==end || fbLayerCount) { // Never touch the framebuffer if we don't have any framebuffer layers if (hwc.getLayerCount(HWC_OVERLAY)) { if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display // when using overlays, we assume a fully transparent framebuffer // NOTE: we could reduce how much we need to clear, for instance // remove where there are opaque FB layers. however, on some Loading
services/surfaceflinger/SurfaceFlinger.h +0 −2 Original line number Diff line number Diff line Loading @@ -237,7 +237,6 @@ private: void handlePageFlip(); void handleRefresh(); void handleWorkList(const DisplayHardware& hw); void handleRepaint(const DisplayHardware& hw, const Region& dirtyRegion); /* ------------------------------------------------------------------------ Loading Loading @@ -339,7 +338,6 @@ private: uint32_t layerStack, Region& dirtyRegion, Region& opaqueRegion); void postFramebuffer(); void setupHardwareComposer(const DisplayHardware& hw); void composeSurfaces(const DisplayHardware& hw, const Region& dirty); void drawWormhole(const Region& region) const; GLuint getProtectedTexName() const { Loading