Merge changes I3f0e01b0,I946cbc78,I9d3ad801 into ics-factoryrom

* changes:
  fix transition from full overlays to fb
  rename mInvalidRegion to mSwapRegion
  improve hwc dumpsys
This commit is contained in:
Mathias Agopian
2011-09-20 18:26:05 -07:00
committed by Android (Google) Code Review
7 changed files with 120 additions and 63 deletions

View File

@@ -84,9 +84,10 @@ public:
status_t compositionComplete() const; status_t compositionComplete() const;
Rect bounds() const { Rect getBounds() const {
return Rect(mWidth, mHeight); return Rect(mWidth, mHeight);
} }
inline Rect bounds() const { return getBounds(); }
// only for debugging // only for debugging
int getCurrentBufferIndex() const; int getCurrentBufferIndex() const;

View File

@@ -40,6 +40,7 @@ namespace android {
HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
: mFlinger(flinger), : mFlinger(flinger),
mModule(0), mHwc(0), mList(0), mCapacity(0), mModule(0), mHwc(0), mList(0), mCapacity(0),
mNumOVLayers(0), mNumFBLayers(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE) mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{ {
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
@@ -98,9 +99,40 @@ status_t HWComposer::createWorkList(size_t numLayers) {
status_t HWComposer::prepare() const { status_t HWComposer::prepare() const {
int err = mHwc->prepare(mHwc, mList); int err = mHwc->prepare(mHwc, mList);
if (err == NO_ERROR) {
size_t numOVLayers = 0;
size_t numFBLayers = 0;
size_t count = mList->numHwLayers;
for (size_t i=0 ; i<count ; i++) {
hwc_layer& l(mList->hwLayers[i]);
if (l.flags & HWC_SKIP_LAYER) {
l.compositionType = HWC_FRAMEBUFFER;
}
switch (l.compositionType) {
case HWC_OVERLAY:
numOVLayers++;
break;
case HWC_FRAMEBUFFER:
numFBLayers++;
break;
}
}
mNumOVLayers = numOVLayers;
mNumFBLayers = numFBLayers;
}
return (status_t)err; return (status_t)err;
} }
size_t HWComposer::getLayerCount(int type) const {
switch (type) {
case HWC_OVERLAY:
return mNumOVLayers;
case HWC_FRAMEBUFFER:
return mNumFBLayers;
}
return 0;
}
status_t HWComposer::commit() const { status_t HWComposer::commit() const {
int err = mHwc->set(mHwc, mDpy, mSur, mList); int err = mHwc->set(mHwc, mDpy, mSur, mList);
if (mList) { if (mList) {
@@ -143,18 +175,29 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
snprintf(buffer, SIZE, " numHwLayers=%u, flags=%08x\n", snprintf(buffer, SIZE, " numHwLayers=%u, flags=%08x\n",
mList->numHwLayers, mList->flags); mList->numHwLayers, mList->flags);
result.append(buffer); result.append(buffer);
result.append(
" type | hints | flags | tr | blend | format | source rectangle | crop rectangle name \n"
"-----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
// " ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
for (size_t i=0 ; i<mList->numHwLayers ; i++) { for (size_t i=0 ; i<mList->numHwLayers ; i++) {
const hwc_layer_t& l(mList->hwLayers[i]); const hwc_layer_t& l(mList->hwLayers[i]);
snprintf(buffer, SIZE, " %8s | %08x | %08x | %02x | %04x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
int32_t format = -1;
if (layer->getLayer() != NULL) {
const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
if (buffer != NULL) {
format = buffer->getPixelFormat();
}
}
snprintf(buffer, SIZE,
" %8s | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
l.compositionType ? "OVERLAY" : "FB", l.compositionType ? "OVERLAY" : "FB",
l.hints, l.flags, l.transform, l.blending, l.hints, l.flags, l.transform, l.blending, format,
l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
visibleLayersSortedByZ[i]->getName().string()); layer->getName().string());
result.append(buffer); result.append(buffer);
} }
} }
if (mHwc && mHwc->common.version >= 1 && mHwc->dump) { if (mHwc && mHwc->common.version >= 1 && mHwc->dump) {
mHwc->dump(mHwc, buffer, SIZE); mHwc->dump(mHwc, buffer, SIZE);

View File

@@ -64,6 +64,9 @@ public:
size_t getNumLayers() const; size_t getNumLayers() const;
hwc_layer_t* getLayers() const; hwc_layer_t* getLayers() const;
// updated in preapre()
size_t getLayerCount(int type) const;
// for debugging // for debugging
void dump(String8& out, char* scratch, size_t SIZE, void dump(String8& out, char* scratch, size_t SIZE,
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const; const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
@@ -81,6 +84,8 @@ private:
hwc_composer_device_t* mHwc; hwc_composer_device_t* mHwc;
hwc_layer_list_t* mList; hwc_layer_list_t* mList;
size_t mCapacity; size_t mCapacity;
mutable size_t mNumOVLayers;
mutable size_t mNumFBLayers;
hwc_display_t mDpy; hwc_display_t mDpy;
hwc_surface_t mSur; hwc_surface_t mSur;
cb_context mCBContext; cb_context mCBContext;

View File

@@ -73,12 +73,14 @@ public:
virtual bool isSecure() const { return mSecure; } virtual bool isSecure() const { return mSecure; }
virtual bool isProtected() const; virtual bool isProtected() const;
virtual void onRemoved(); virtual void onRemoved();
virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
// LayerBaseClient interface // LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const; virtual wp<IBinder> getSurfaceTextureBinder() const;
// only for debugging // only for debugging
inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; } inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
protected: protected:
virtual void onFirstRef(); virtual void onFirstRef();

View File

@@ -46,6 +46,7 @@ class Client;
class DisplayHardware; class DisplayHardware;
class GraphicBuffer; class GraphicBuffer;
class GraphicPlane; class GraphicPlane;
class Layer;
class LayerBaseClient; class LayerBaseClient;
class SurfaceFlinger; class SurfaceFlinger;
@@ -105,6 +106,7 @@ public:
void invalidate(); void invalidate();
virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; } virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
virtual sp<Layer> getLayer() const { return 0; }
virtual const char* getTypeId() const { return "LayerBase"; } virtual const char* getTypeId() const { return "LayerBase"; }

View File

@@ -469,14 +469,14 @@ bool SurfaceFlinger::threadLoop()
void SurfaceFlinger::postFramebuffer() void SurfaceFlinger::postFramebuffer()
{ {
if (!mInvalidRegion.isEmpty()) { if (!mSwapRegion.isEmpty()) {
const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware());
const nsecs_t now = systemTime(); const nsecs_t now = systemTime();
mDebugInSwapBuffers = now; mDebugInSwapBuffers = now;
hw.flip(mInvalidRegion); hw.flip(mSwapRegion);
mLastSwapBufferTime = systemTime() - now; mLastSwapBufferTime = systemTime() - now;
mDebugInSwapBuffers = 0; mDebugInSwapBuffers = 0;
mInvalidRegion.clear(); mSwapRegion.clear();
} }
} }
@@ -834,7 +834,7 @@ void SurfaceFlinger::handleWorkList()
void SurfaceFlinger::handleRepaint() void SurfaceFlinger::handleRepaint()
{ {
// compute the invalid region // compute the invalid region
mInvalidRegion.orSelf(mDirtyRegion); mSwapRegion.orSelf(mDirtyRegion);
if (UNLIKELY(mDebugRegion)) { if (UNLIKELY(mDebugRegion)) {
debugFlashRegions(); debugFlashRegions();
@@ -855,7 +855,7 @@ void SurfaceFlinger::handleRepaint()
if (flags & DisplayHardware::SWAP_RECTANGLE) { if (flags & DisplayHardware::SWAP_RECTANGLE) {
// TODO: we really should be able to pass a region to // TODO: we really should be able to pass a region to
// SWAP_RECTANGLE so that we don't have to redraw all this. // SWAP_RECTANGLE so that we don't have to redraw all this.
mDirtyRegion.set(mInvalidRegion.bounds()); mDirtyRegion.set(mSwapRegion.bounds());
} else { } else {
// in the BUFFER_PRESERVED case, obviously, we can update only // in the BUFFER_PRESERVED case, obviously, we can update only
// what's needed and nothing more. // what's needed and nothing more.
@@ -868,32 +868,29 @@ void SurfaceFlinger::handleRepaint()
// (pushed to the framebuffer). // (pushed to the framebuffer).
// This is needed because PARTIAL_UPDATES only takes one // This is needed because PARTIAL_UPDATES only takes one
// rectangle instead of a region (see DisplayHardware::flip()) // rectangle instead of a region (see DisplayHardware::flip())
mDirtyRegion.set(mInvalidRegion.bounds()); mDirtyRegion.set(mSwapRegion.bounds());
} else { } else {
// we need to redraw everything (the whole screen) // we need to redraw everything (the whole screen)
mDirtyRegion.set(hw.bounds()); mDirtyRegion.set(hw.bounds());
mInvalidRegion = mDirtyRegion; mSwapRegion = mDirtyRegion;
} }
} }
Region expandDirty = setupHardwareComposer(mDirtyRegion); setupHardwareComposer(mDirtyRegion);
mDirtyRegion.orSelf(expandDirty);
mInvalidRegion.orSelf(mDirtyRegion);
composeSurfaces(mDirtyRegion); composeSurfaces(mDirtyRegion);
// clear the dirty regions // update the swap region and clear the dirty region
mSwapRegion.orSelf(mDirtyRegion);
mDirtyRegion.clear(); mDirtyRegion.clear();
} }
Region SurfaceFlinger::setupHardwareComposer(const Region& dirty) void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
{ {
Region dirtyOut(dirty);
const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer()); HWComposer& hwc(hw.getHwComposer());
hwc_layer_t* const cur(hwc.getLayers()); hwc_layer_t* const cur(hwc.getLayers());
if (!cur) { if (!cur) {
return dirtyOut; return;
} }
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
@@ -916,53 +913,62 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
const sp<LayerBase>& layer(layers[i]); const sp<LayerBase>& layer(layers[i]);
layer->setPerFrameData(&cur[i]); layer->setPerFrameData(&cur[i]);
} }
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
status_t err = hwc.prepare(); status_t err = hwc.prepare();
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
if (err == NO_ERROR) { if (err == NO_ERROR) {
// what's happening here is tricky.
// we want to clear all the layers with the CLEAR_FB flags
// that are opaque.
// however, since some GPU are efficient at preserving
// the backbuffer, we want to take advantage of that so we do the
// clear only in the dirty region (other areas will be preserved
// on those GPUs).
// NOTE: on non backbuffer preserving GPU, the dirty region
// has already been expanded as needed, so the code is correct
// there too.
//
// However, the content of the framebuffer cannot be trusted when
// we switch to/from FB/OVERLAY, in which case we need to
// expand the dirty region to those areas too.
//
// Note also that there is a special case when switching from
// "no layers in FB" to "some layers in FB", where we need to redraw
// the entire FB, since some areas might contain uninitialized
// data.
//
// Also we want to make sure to not clear areas that belong to
// layers above that won't redraw (we would just erasing them),
// that is, we can't erase anything outside the dirty region.
Region transparent; Region transparent;
for (size_t i=0 ; i<count ; i++) {
// what's happening here is tricky.
// we want to clear all the layers with the CLEAR_FB flags
// that are opaque.
// however, since some GPU have are efficient at preserving
// the backbuffer, we want to take advantage of that so we do the
// clear only in the dirty region (other areas will be preserved
// on those GPUs).
// NOTE: on non backbuffer preserving GPU, the dirty region
// has already been expanded as needed, so the code is correct
// there too.
// However, the content of the framebuffer cannot be trusted when
// we switch to/from FB/OVERLAY, in which case we need to
// expand the dirty region to those areas too.
//
// Also we want to make sure to not clear areas that belong to
// layers above that won't redraw (we would just erasing them),
// that is, we can't erase anything outside the dirty region.
const sp<LayerBase>& layer(layers[i]); if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { transparent.set(hw.getBounds());
transparent.orSelf(layer->visibleRegionScreen); dirtyInOut = transparent;
} else {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(layers[i]);
if ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
transparent.orSelf(layer->visibleRegionScreen);
}
bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER);
if (isOverlay != layer->isOverlay()) {
// we transitioned to/from overlay, so add this layer
// to the dirty region so the framebuffer can be either
// cleared or redrawn.
dirtyInOut.orSelf(layer->visibleRegionScreen);
}
layer->setOverlay(isOverlay);
} }
// don't erase stuff outside the dirty region
bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) && transparent.andSelf(dirtyInOut);
!(cur[i].flags & HWC_SKIP_LAYER);
if (isOverlay != layer->isOverlay()) {
// we transitioned to/from overlay, so add this layer
// to the dirty region so the framebuffer can be either
// cleared or redrawn.
dirtyOut.orSelf(layer->visibleRegionScreen);
}
layer->setOverlay(isOverlay);
} }
/* /*
* clear the area of the FB that need to be transparent * clear the area of the FB that need to be transparent
*/ */
// don't erase stuff outside the dirty region
transparent.andSelf(dirtyOut);
if (!transparent.isEmpty()) { if (!transparent.isEmpty()) {
glClearColor(0,0,0,0); glClearColor(0,0,0,0);
Region::const_iterator it = transparent.begin(); Region::const_iterator it = transparent.begin();
@@ -976,7 +982,6 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
} }
} }
} }
return dirtyOut;
} }
void SurfaceFlinger::composeSurfaces(const Region& dirty) void SurfaceFlinger::composeSurfaces(const Region& dirty)
@@ -997,8 +1002,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
size_t count = layers.size(); size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) { for (size_t i=0 ; i<count ; i++) {
if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) && if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
!(cur[i].flags & HWC_SKIP_LAYER)) {
continue; continue;
} }
const sp<LayerBase>& layer(layers[i]); const sp<LayerBase>& layer(layers[i]);
@@ -1014,7 +1018,7 @@ void SurfaceFlinger::debugFlashRegions()
const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware());
const uint32_t flags = hw.getFlags(); const uint32_t flags = hw.getFlags();
const int32_t height = hw.getHeight(); const int32_t height = hw.getHeight();
if (mInvalidRegion.isEmpty()) { if (mSwapRegion.isEmpty()) {
return; return;
} }
@@ -1051,7 +1055,7 @@ void SurfaceFlinger::debugFlashRegions()
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
} }
hw.flip(mInvalidRegion); hw.flip(mSwapRegion);
if (mDebugRegion > 1) if (mDebugRegion > 1)
usleep(mDebugRegion * 1000); usleep(mDebugRegion * 1000);

View File

@@ -277,7 +277,7 @@ private:
void handleWorkList(); void handleWorkList();
void handleRepaint(); void handleRepaint();
void postFramebuffer(); void postFramebuffer();
Region setupHardwareComposer(const Region& dirty); void setupHardwareComposer(Region& dirtyInOut);
void composeSurfaces(const Region& dirty); void composeSurfaces(const Region& dirty);
void repaintEverything(); void repaintEverything();
@@ -358,7 +358,7 @@ private:
State mDrawingState; State mDrawingState;
Region mDirtyRegion; Region mDirtyRegion;
Region mDirtyRegionRemovedLayer; Region mDirtyRegionRemovedLayer;
Region mInvalidRegion; Region mSwapRegion;
Region mWormholeRegion; Region mWormholeRegion;
bool mVisibleRegionsDirty; bool mVisibleRegionsDirty;
bool mHwWorkListDirty; bool mHwWorkListDirty;