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:
committed by
Android (Google) Code Review
commit
6db5b55f7c
@@ -84,9 +84,10 @@ public:
|
||||
|
||||
status_t compositionComplete() const;
|
||||
|
||||
Rect bounds() const {
|
||||
Rect getBounds() const {
|
||||
return Rect(mWidth, mHeight);
|
||||
}
|
||||
inline Rect bounds() const { return getBounds(); }
|
||||
|
||||
// only for debugging
|
||||
int getCurrentBufferIndex() const;
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace android {
|
||||
HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger)
|
||||
: mFlinger(flinger),
|
||||
mModule(0), mHwc(0), mList(0), mCapacity(0),
|
||||
mNumOVLayers(0), mNumFBLayers(0),
|
||||
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
|
||||
{
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
int err = mHwc->set(mHwc, mDpy, mSur, 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",
|
||||
mList->numHwLayers, mList->flags);
|
||||
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++) {
|
||||
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.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.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
|
||||
visibleLayersSortedByZ[i]->getName().string());
|
||||
layer->getName().string());
|
||||
result.append(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
if (mHwc && mHwc->common.version >= 1 && mHwc->dump) {
|
||||
mHwc->dump(mHwc, buffer, SIZE);
|
||||
|
||||
@@ -64,6 +64,9 @@ public:
|
||||
size_t getNumLayers() const;
|
||||
hwc_layer_t* getLayers() const;
|
||||
|
||||
// updated in preapre()
|
||||
size_t getLayerCount(int type) const;
|
||||
|
||||
// for debugging
|
||||
void dump(String8& out, char* scratch, size_t SIZE,
|
||||
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
|
||||
@@ -81,6 +84,8 @@ private:
|
||||
hwc_composer_device_t* mHwc;
|
||||
hwc_layer_list_t* mList;
|
||||
size_t mCapacity;
|
||||
mutable size_t mNumOVLayers;
|
||||
mutable size_t mNumFBLayers;
|
||||
hwc_display_t mDpy;
|
||||
hwc_surface_t mSur;
|
||||
cb_context mCBContext;
|
||||
|
||||
@@ -73,12 +73,14 @@ public:
|
||||
virtual bool isSecure() const { return mSecure; }
|
||||
virtual bool isProtected() const;
|
||||
virtual void onRemoved();
|
||||
virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
|
||||
|
||||
// LayerBaseClient interface
|
||||
virtual wp<IBinder> getSurfaceTextureBinder() const;
|
||||
|
||||
// only for debugging
|
||||
inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; }
|
||||
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
|
||||
|
||||
protected:
|
||||
virtual void onFirstRef();
|
||||
|
||||
@@ -46,6 +46,7 @@ class Client;
|
||||
class DisplayHardware;
|
||||
class GraphicBuffer;
|
||||
class GraphicPlane;
|
||||
class Layer;
|
||||
class LayerBaseClient;
|
||||
class SurfaceFlinger;
|
||||
|
||||
@@ -105,6 +106,7 @@ public:
|
||||
void invalidate();
|
||||
|
||||
virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
|
||||
virtual sp<Layer> getLayer() const { return 0; }
|
||||
|
||||
virtual const char* getTypeId() const { return "LayerBase"; }
|
||||
|
||||
|
||||
@@ -469,14 +469,14 @@ bool SurfaceFlinger::threadLoop()
|
||||
|
||||
void SurfaceFlinger::postFramebuffer()
|
||||
{
|
||||
if (!mInvalidRegion.isEmpty()) {
|
||||
if (!mSwapRegion.isEmpty()) {
|
||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||
const nsecs_t now = systemTime();
|
||||
mDebugInSwapBuffers = now;
|
||||
hw.flip(mInvalidRegion);
|
||||
hw.flip(mSwapRegion);
|
||||
mLastSwapBufferTime = systemTime() - now;
|
||||
mDebugInSwapBuffers = 0;
|
||||
mInvalidRegion.clear();
|
||||
mSwapRegion.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,7 +834,7 @@ void SurfaceFlinger::handleWorkList()
|
||||
void SurfaceFlinger::handleRepaint()
|
||||
{
|
||||
// compute the invalid region
|
||||
mInvalidRegion.orSelf(mDirtyRegion);
|
||||
mSwapRegion.orSelf(mDirtyRegion);
|
||||
|
||||
if (UNLIKELY(mDebugRegion)) {
|
||||
debugFlashRegions();
|
||||
@@ -855,7 +855,7 @@ void SurfaceFlinger::handleRepaint()
|
||||
if (flags & DisplayHardware::SWAP_RECTANGLE) {
|
||||
// TODO: we really should be able to pass a region to
|
||||
// SWAP_RECTANGLE so that we don't have to redraw all this.
|
||||
mDirtyRegion.set(mInvalidRegion.bounds());
|
||||
mDirtyRegion.set(mSwapRegion.bounds());
|
||||
} else {
|
||||
// in the BUFFER_PRESERVED case, obviously, we can update only
|
||||
// what's needed and nothing more.
|
||||
@@ -868,32 +868,29 @@ void SurfaceFlinger::handleRepaint()
|
||||
// (pushed to the framebuffer).
|
||||
// This is needed because PARTIAL_UPDATES only takes one
|
||||
// rectangle instead of a region (see DisplayHardware::flip())
|
||||
mDirtyRegion.set(mInvalidRegion.bounds());
|
||||
mDirtyRegion.set(mSwapRegion.bounds());
|
||||
} else {
|
||||
// we need to redraw everything (the whole screen)
|
||||
mDirtyRegion.set(hw.bounds());
|
||||
mInvalidRegion = mDirtyRegion;
|
||||
mSwapRegion = mDirtyRegion;
|
||||
}
|
||||
}
|
||||
|
||||
Region expandDirty = setupHardwareComposer(mDirtyRegion);
|
||||
mDirtyRegion.orSelf(expandDirty);
|
||||
mInvalidRegion.orSelf(mDirtyRegion);
|
||||
setupHardwareComposer(mDirtyRegion);
|
||||
composeSurfaces(mDirtyRegion);
|
||||
|
||||
// clear the dirty regions
|
||||
// update the swap region and clear the dirty region
|
||||
mSwapRegion.orSelf(mDirtyRegion);
|
||||
mDirtyRegion.clear();
|
||||
}
|
||||
|
||||
Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
|
||||
void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
|
||||
{
|
||||
Region dirtyOut(dirty);
|
||||
|
||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||
HWComposer& hwc(hw.getHwComposer());
|
||||
hwc_layer_t* const cur(hwc.getLayers());
|
||||
if (!cur) {
|
||||
return dirtyOut;
|
||||
return;
|
||||
}
|
||||
|
||||
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
|
||||
@@ -916,53 +913,62 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
|
||||
const sp<LayerBase>& layer(layers[i]);
|
||||
layer->setPerFrameData(&cur[i]);
|
||||
}
|
||||
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
|
||||
status_t err = hwc.prepare();
|
||||
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
||||
|
||||
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;
|
||||
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 ((cur[i].hints & HWC_HINT_CLEAR_FB) && layer->isOpaque()) {
|
||||
transparent.orSelf(layer->visibleRegionScreen);
|
||||
if (!fbLayerCount && hwc.getLayerCount(HWC_FRAMEBUFFER)) {
|
||||
transparent.set(hw.getBounds());
|
||||
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);
|
||||
}
|
||||
|
||||
bool isOverlay = (cur[i].compositionType != HWC_FRAMEBUFFER) &&
|
||||
!(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);
|
||||
// don't erase stuff outside the dirty region
|
||||
transparent.andSelf(dirtyInOut);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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()) {
|
||||
glClearColor(0,0,0,0);
|
||||
Region::const_iterator it = transparent.begin();
|
||||
@@ -976,7 +982,6 @@ Region SurfaceFlinger::setupHardwareComposer(const Region& dirty)
|
||||
}
|
||||
}
|
||||
}
|
||||
return dirtyOut;
|
||||
}
|
||||
|
||||
void SurfaceFlinger::composeSurfaces(const Region& dirty)
|
||||
@@ -997,8 +1002,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
|
||||
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
|
||||
size_t count = layers.size();
|
||||
for (size_t i=0 ; i<count ; i++) {
|
||||
if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER) &&
|
||||
!(cur[i].flags & HWC_SKIP_LAYER)) {
|
||||
if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
|
||||
continue;
|
||||
}
|
||||
const sp<LayerBase>& layer(layers[i]);
|
||||
@@ -1014,7 +1018,7 @@ void SurfaceFlinger::debugFlashRegions()
|
||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||
const uint32_t flags = hw.getFlags();
|
||||
const int32_t height = hw.getHeight();
|
||||
if (mInvalidRegion.isEmpty()) {
|
||||
if (mSwapRegion.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1051,7 +1055,7 @@ void SurfaceFlinger::debugFlashRegions()
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
hw.flip(mInvalidRegion);
|
||||
hw.flip(mSwapRegion);
|
||||
|
||||
if (mDebugRegion > 1)
|
||||
usleep(mDebugRegion * 1000);
|
||||
|
||||
@@ -277,7 +277,7 @@ private:
|
||||
void handleWorkList();
|
||||
void handleRepaint();
|
||||
void postFramebuffer();
|
||||
Region setupHardwareComposer(const Region& dirty);
|
||||
void setupHardwareComposer(Region& dirtyInOut);
|
||||
void composeSurfaces(const Region& dirty);
|
||||
void repaintEverything();
|
||||
|
||||
@@ -358,7 +358,7 @@ private:
|
||||
State mDrawingState;
|
||||
Region mDirtyRegion;
|
||||
Region mDirtyRegionRemovedLayer;
|
||||
Region mInvalidRegion;
|
||||
Region mSwapRegion;
|
||||
Region mWormholeRegion;
|
||||
bool mVisibleRegionsDirty;
|
||||
bool mHwWorkListDirty;
|
||||
|
||||
Reference in New Issue
Block a user