diff options
author | Mathias Agopian <mathias@google.com> | 2010-08-12 15:03:26 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2010-08-12 15:03:26 -0700 |
commit | 45721773e1a68e96da4b6cc04cef276bae7ca3e9 (patch) | |
tree | 1b47e306c6fd15fc5c182aa0d22140f0c3edc171 /services/surfaceflinger/SurfaceFlinger.cpp | |
parent | f1352df47fe20aed23c216a78923c7d248f2bb91 (diff) | |
download | frameworks_native-45721773e1a68e96da4b6cc04cef276bae7ca3e9.zip frameworks_native-45721773e1a68e96da4b6cc04cef276bae7ca3e9.tar.gz frameworks_native-45721773e1a68e96da4b6cc04cef276bae7ca3e9.tar.bz2 |
Fix a couple issues with the new hwcomposer HAL
- we now clear the framebuffer upon request from the HAL
- the HAL list size could get out of sync with reality
- there was also an issue where sometime we could run past the list
Change-Id: Ic3a34314aed24181f2d8cc787096af83c046ef27
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 82 |
1 files changed, 47 insertions, 35 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 47bb4c1..006bb10 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -755,10 +755,9 @@ void SurfaceFlinger::handleWorkList() const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); const size_t count = currentLayers.size(); hwc.createWorkList(count); - HWComposer::iterator cur(hwc.begin()); - HWComposer::iterator last(hwc.end()); - for (size_t i=0 ; (i<count) && (cur!=last) ; ++i, ++cur) { - currentLayers[i]->setGeometry(cur); + hwc_layer_t* const cur(hwc.getLayers()); + for (size_t i=0 ; cur && i<count ; i++) { + currentLayers[i]->setGeometry(&cur[i]); } } } @@ -829,47 +828,41 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) status_t err = NO_ERROR; const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); - const size_t count = layers.size(); + size_t count = layers.size(); const DisplayHardware& hw(graphicPlane(0).displayHardware()); HWComposer& hwc(hw.getHwComposer()); - HWComposer::iterator cur(hwc.begin()); - HWComposer::iterator last(hwc.end()); + hwc_layer_t* const cur(hwc.getLayers()); - // update the per-frame h/w composer data for each layer - if (cur != last) { - for (size_t i=0 ; i<count && cur!=last ; ++i, ++cur) { - layers[i]->setPerFrameData(cur); - } - err = hwc.prepare(); - LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); - } + LOGE_IF(cur && hwc.getNumLayers() != count, + "HAL number of layers (%d) doesn't match surfaceflinger (%d)", + hwc.getNumLayers(), count); - // and then, render the layers targeted at the framebuffer - Region transparent(hw.bounds()); - for (size_t i=0 ; i<count ; ++i) { + // just to be extra-safe, use the smallest count + count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); - // see if we need to skip this layer - if (!err && cur != last) { - if (!((cur->compositionType == HWC_FRAMEBUFFER) || - (cur->flags & HWC_SKIP_LAYER))) { - ++cur; - continue; + /* + * update the per-frame h/w composer data for each layer + * and build the transparent region of the FB + */ + Region transparent; + if (cur) { + for (size_t i=0 ; i<count ; i++) { + const sp<LayerBase>& layer(layers[i]); + layer->setPerFrameData(&cur[i]); + if (cur[i].hints & HWC_HINT_CLEAR_FB) { + if (!(layer->needsBlending())) { + transparent.orSelf(layer->visibleRegionScreen); + } } - ++cur; - } - - // draw the layer into the framebuffer - const sp<LayerBase>& layer(layers[i]); - transparent.subtractSelf(layer->visibleRegionScreen); - const Region clip(dirty.intersect(layer->visibleRegionScreen)); - if (!clip.isEmpty()) { - layer->draw(clip); } + err = hwc.prepare(); + LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); } - // finally clear everything we didn't draw as a result of calling - // prepare (this leaves the FB transparent). + /* + * clear the area of the FB that need to be transparent + */ transparent.andSelf(dirty); if (!transparent.isEmpty()) { glClearColor(0,0,0,0); @@ -883,6 +876,25 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) glClear(GL_COLOR_BUFFER_BIT); } } + + + /* + * and then, render the layers targeted at the framebuffer + */ + for (size_t i=0 ; i<count ; i++) { + if (cur) { + if (!(cur[i].compositionType == HWC_FRAMEBUFFER) || + cur[i].flags & HWC_SKIP_LAYER) { + // skip layers handled by the HAL + continue; + } + } + const sp<LayerBase>& layer(layers[i]); + const Region clip(dirty.intersect(layer->visibleRegionScreen)); + if (!clip.isEmpty()) { + layer->draw(clip); + } + } } void SurfaceFlinger::unlockClients() |