Merge changes Id79430f9,I541d3046
* changes:
BufferQueue: check before tracing buffer index
SurfaceTexture: shrink all sides when cropping
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index c0e90b3..6644751 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -26,6 +26,7 @@
#include <utils/RefBase.h>
#include <utils/threads.h>
+#include <utils/KeyedVector.h>
struct ANativeWindow_Buffer;
@@ -113,6 +114,11 @@
void freeAllBuffers();
int getSlotFromBufferLocked(android_native_buffer_t* buffer) const;
+ struct BufferSlot {
+ sp<GraphicBuffer> buffer;
+ Region dirtyRegion;
+ };
+
// mSurfaceTexture is the interface to the surface texture server. All
// operations on the surface texture client ultimately translate into
// interactions with the server using this interface.
@@ -124,7 +130,7 @@
// slot that has not yet been used. The buffer allocated to a slot will also
// be replaced if the requested buffer usage or geometry differs from that
// of the buffer allocated to a slot.
- sp<GraphicBuffer> mSlots[NUM_BUFFER_SLOTS];
+ BufferSlot mSlots[NUM_BUFFER_SLOTS];
// mReqWidth is the buffer width that will be requested at the next dequeue
// operation. It is initialized to 1.
@@ -189,8 +195,10 @@
// must be used from the lock/unlock thread
sp<GraphicBuffer> mLockedBuffer;
sp<GraphicBuffer> mPostedBuffer;
- mutable Region mOldDirtyRegion;
bool mConnectedToCpu;
+
+ // must be accessed from lock/unlock thread only
+ Region mDirtyRegion;
};
}; // namespace android
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h
index 8d76533..421bdda 100644
--- a/include/private/ui/RegionHelper.h
+++ b/include/private/ui/RegionHelper.h
@@ -96,6 +96,11 @@
class SpannerBase
{
public:
+ SpannerBase()
+ : lhs_head(max_value), lhs_tail(max_value),
+ rhs_head(max_value), rhs_tail(max_value) {
+ }
+
enum {
lhs_before_rhs = 0,
lhs_after_rhs = 1,
@@ -158,12 +163,16 @@
public:
inline Spanner(const region& lhs, const region& rhs)
- : lhs(lhs), rhs(rhs)
+ : lhs(lhs), rhs(rhs)
{
- SpannerBase::lhs_head = lhs.rects->top + lhs.dy;
- SpannerBase::lhs_tail = lhs.rects->bottom + lhs.dy;
- SpannerBase::rhs_head = rhs.rects->top + rhs.dy;
- SpannerBase::rhs_tail = rhs.rects->bottom + rhs.dy;
+ if (lhs.count) {
+ SpannerBase::lhs_head = lhs.rects->top + lhs.dy;
+ SpannerBase::lhs_tail = lhs.rects->bottom + lhs.dy;
+ }
+ if (rhs.count) {
+ SpannerBase::rhs_head = rhs.rects->top + rhs.dy;
+ SpannerBase::rhs_tail = rhs.rects->bottom + rhs.dy;
+ }
}
inline bool isDone() const {
@@ -221,20 +230,28 @@
inline void prepare(int inside) {
if (inside == SpannerBase::lhs_before_rhs) {
- SpannerBase::lhs_head = lhs.rects->left + lhs.dx;
- SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
+ if (lhs.count) {
+ SpannerBase::lhs_head = lhs.rects->left + lhs.dx;
+ SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
+ }
SpannerBase::rhs_head = max_value;
SpannerBase::rhs_tail = max_value;
} else if (inside == SpannerBase::lhs_after_rhs) {
SpannerBase::lhs_head = max_value;
SpannerBase::lhs_tail = max_value;
- SpannerBase::rhs_head = rhs.rects->left + rhs.dx;
- SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
+ if (rhs.count) {
+ SpannerBase::rhs_head = rhs.rects->left + rhs.dx;
+ SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
+ }
} else {
- SpannerBase::lhs_head = lhs.rects->left + lhs.dx;
- SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
- SpannerBase::rhs_head = rhs.rects->left + rhs.dx;
- SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
+ if (lhs.count) {
+ SpannerBase::lhs_head = lhs.rects->left + lhs.dx;
+ SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
+ }
+ if (rhs.count) {
+ SpannerBase::rhs_head = rhs.rects->left + rhs.dx;
+ SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
+ }
}
}
diff --git a/include/utils/Trace.h b/include/utils/Trace.h
index a2429c0..637c146 100644
--- a/include/utils/Trace.h
+++ b/include/utils/Trace.h
@@ -45,7 +45,8 @@
#define ATRACE_TAG_GRAPHICS (1<<1)
#define ATRACE_TAG_INPUT (1<<2)
#define ATRACE_TAG_VIEW (1<<3)
-#define ATRACE_TAG_LAST ATRACE_TAG_VIEW
+#define ATRACE_TAG_WEBVIEW (1<<4)
+#define ATRACE_TAG_LAST ATRACE_TAG_WEBVIEW
#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 9fa412c..5399e52 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -73,10 +73,11 @@
sp<ProcessState> ProcessState::self()
{
- if (gProcess != NULL) return gProcess;
-
- AutoMutex _l(gProcessMutex);
- if (gProcess == NULL) gProcess = new ProcessState;
+ Mutex::Autolock _l(gProcessMutex);
+ if (gProcess != NULL) {
+ return gProcess;
+ }
+ gProcess = new ProcessState;
return gProcess;
}
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 99c025f..b37d821 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -171,7 +171,7 @@
result);
return result;
}
- sp<GraphicBuffer>& gbuf(mSlots[buf]);
+ sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {
freeAllBuffers();
}
@@ -204,7 +204,8 @@
android_native_buffer_t* buffer) const {
bool dumpedState = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- if (mSlots[i] != NULL && mSlots[i]->handle == buffer->handle) {
+ if (mSlots[i].buffer != NULL &&
+ mSlots[i].buffer->handle == buffer->handle) {
return i;
}
}
@@ -586,7 +587,7 @@
void SurfaceTextureClient::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- mSlots[i] = 0;
+ mSlots[i].buffer = 0;
}
}
@@ -691,19 +692,32 @@
if (canCopyBack) {
// copy the area that is invalid and not repainted this round
- const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
+ const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
if (!copyback.isEmpty())
copyBlt(backBuffer, frontBuffer, copyback);
} else {
// if we can't copy-back anything, modify the user's dirty
// region to make sure they redraw the whole buffer
newDirtyRegion.set(bounds);
+ mDirtyRegion.clear();
+ Mutex::Autolock lock(mMutex);
+ for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
+ mSlots[i].dirtyRegion.clear();
+ }
}
- // keep track of the are of the buffer that is "clean"
- // (ie: that will be redrawn)
- mOldDirtyRegion = newDirtyRegion;
+ { // scope for the lock
+ Mutex::Autolock lock(mMutex);
+ int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
+ if (backBufferSlot >= 0) {
+ Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
+ mDirtyRegion.subtract(dirtyRegion);
+ dirtyRegion = newDirtyRegion;
+ }
+ }
+
+ mDirtyRegion.orSelf(newDirtyRegion);
if (inOutDirtyBounds) {
*inOutDirtyBounds = newDirtyRegion.getBounds();
}
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 6e2e731..2c7cdf0 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -619,7 +619,15 @@
}
Region::const_iterator Region::end() const {
- return isRect() ? ((&mBounds) + 1) : (mStorage.array() + mStorage.size());
+ if (isRect()) {
+ if (isEmpty()) {
+ return &mBounds;
+ } else {
+ return &mBounds + 1;
+ }
+ } else {
+ return mStorage.array() + mStorage.size();
+ }
}
Rect const* Region::getArray(size_t* count) const {
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index c46e630..48651b6 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -280,12 +280,6 @@
EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
}
- if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
- if (dummy == EGL_BUFFER_PRESERVED) {
- mFlags |= BUFFER_PRESERVED;
- }
- }
-
/*
* Create our OpenGL ES context
*/
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 84a3eff..f1dee91 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -51,7 +51,6 @@
enum {
COPY_BITS_EXTENSION = 0x00000008,
- BUFFER_PRESERVED = 0x00010000,
PARTIAL_UPDATES = 0x00020000, // video driver feature
SLOW_CONFIG = 0x00040000, // software
SWAP_RECTANGLE = 0x00080000,
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index e764001..694ecde 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -43,7 +43,7 @@
: dpy(display), contentDirty(false),
sequence(uint32_t(android_atomic_inc(&sSequence))),
mFlinger(flinger), mFiltering(false),
- mNeedsFiltering(false), mInOverlay(false),
+ mNeedsFiltering(false),
mOrientation(0),
mPlaneOrientation(0),
mTransactionFlags(0),
@@ -231,7 +231,9 @@
const uint32_t hw_h = hw.getHeight();
uint32_t w = s.w;
- uint32_t h = s.h;
+ uint32_t h = s.h;
+
+ mNumVertices = 4;
tr.transform(mVertices[0], 0, 0);
tr.transform(mVertices[1], 0, h);
tr.transform(mVertices[2], w, h);
@@ -268,27 +270,6 @@
const Transform& planeTransform, Region& outDirtyRegion) {
}
-void LayerBase::drawRegion(const Region& reg) const
-{
- Region::const_iterator it = reg.begin();
- Region::const_iterator const end = reg.end();
- if (it != end) {
- Rect r;
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const int32_t fbWidth = hw.getWidth();
- const int32_t fbHeight = hw.getHeight();
- const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 },
- { fbWidth, fbHeight }, { 0, fbHeight } };
- glVertexPointer(2, GL_SHORT, 0, vertices);
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- }
-}
-
void LayerBase::setGeometry(hwc_layer_t* hwcl)
{
hwcl->compositionType = HWC_FRAMEBUFFER;
@@ -333,14 +314,6 @@
hwcl->handle = NULL;
}
-void LayerBase::setOverlay(bool inOverlay) {
- mInOverlay = inOverlay;
-}
-
-bool LayerBase::isOverlay() const {
- return mInOverlay;
-}
-
void LayerBase::setFiltering(bool filtering)
{
mFiltering = filtering;
@@ -353,9 +326,6 @@
void LayerBase::draw(const Region& clip) const
{
- // reset GL state
- glEnable(GL_SCISSOR_TEST);
-
onDraw(clip);
}
@@ -379,16 +349,8 @@
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
- Region::const_iterator it = clip.begin();
- Region::const_iterator const end = clip.end();
- glEnable(GL_SCISSOR_TEST);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
}
void LayerBase::clearWithOpenGL(const Region& clip) const
@@ -442,15 +404,8 @@
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
- Region::const_iterator it = clip.begin();
- Region::const_iterator const end = clip.end();
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
}
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index cd6efdd..d123d9b 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -100,7 +100,6 @@
uint32_t setTransactionFlags(uint32_t flags);
Rect visibleBounds() const;
- void drawRegion(const Region& reg) const;
virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
virtual sp<Layer> getLayer() const { return 0; }
@@ -109,8 +108,6 @@
virtual void setGeometry(hwc_layer_t* hwcl);
virtual void setPerFrameData(hwc_layer_t* hwcl);
- void setOverlay(bool inOverlay);
- bool isOverlay() const;
/**
@@ -230,14 +227,15 @@
int32_t getOrientation() const { return mOrientation; }
int32_t getPlaneOrientation() const { return mPlaneOrientation; }
-
+
+ void clearWithOpenGL(const Region& clip) const;
+
protected:
const GraphicPlane& graphicPlane(int dpy) const;
GraphicPlane& graphicPlane(int dpy);
void clearWithOpenGL(const Region& clip, GLclampf r, GLclampf g,
GLclampf b, GLclampf alpha) const;
- void clearWithOpenGL(const Region& clip) const;
void drawWithOpenGL(const Region& clip) const;
void setFiltering(bool filtering);
@@ -255,17 +253,13 @@
// Whether filtering is needed b/c of the drawingstate
bool mNeedsFiltering;
- // this layer is currently handled by the hwc. this is
- // updated at composition time, always frmo the composition
- // thread.
- bool mInOverlay;
-
protected:
// cached during validateVisibility()
int32_t mOrientation;
int32_t mPlaneOrientation;
Transform mTransform;
GLfloat mVertices[4][2];
+ size_t mNumVertices;
Rect mTransformedBounds;
// these are protected by an external lock
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index e665d7a..96a310f 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -43,9 +43,7 @@
void LayerDim::onDraw(const Region& clip) const
{
const State& s(drawingState());
- Region::const_iterator it = clip.begin();
- Region::const_iterator const end = clip.end();
- if (s.alpha>0 && (it != end)) {
+ if (s.alpha>0) {
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const GLfloat alpha = s.alpha/255.0f;
const uint32_t fbHeight = hw.getHeight();
@@ -62,13 +60,8 @@
glColor4f(0, 0, 0, alpha);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
glDisable(GL_BLEND);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index c7cf46e..b42353c 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -70,8 +70,6 @@
glBindTexture(GL_TEXTURE_2D, mTextureName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
mTexCoords[0] = 0; mTexCoords[1] = v;
mTexCoords[2] = 0; mTexCoords[3] = 0;
mTexCoords[4] = u; mTexCoords[5] = 0;
@@ -111,9 +109,7 @@
void LayerScreenshot::onDraw(const Region& clip) const
{
const State& s(drawingState());
- Region::const_iterator it = clip.begin();
- Region::const_iterator const end = clip.end();
- if (s.alpha>0 && (it != end)) {
+ if (s.alpha>0) {
const DisplayHardware& hw(graphicPlane(0).displayHardware());
const GLfloat alpha = s.alpha/255.0f;
const uint32_t fbHeight = hw.getHeight();
@@ -139,13 +135,7 @@
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
glVertexPointer(2, GL_FLOAT, 0, mVertices);
-
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = fbHeight - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fb0c305..93dd3a4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -265,7 +265,6 @@
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glEnableClientState(GL_VERTEX_ARRAY);
- glEnable(GL_SCISSOR_TEST);
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_CULL_FACE);
@@ -834,22 +833,11 @@
glLoadIdentity();
uint32_t flags = hw.getFlags();
- if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
- (flags & DisplayHardware::BUFFER_PRESERVED))
- {
+ if (flags & DisplayHardware::SWAP_RECTANGLE) {
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
// takes a rectangle, we must make sure to update that whole
// rectangle in that case
- 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(mSwapRegion.bounds());
- } else {
- // in the BUFFER_PRESERVED case, obviously, we can update only
- // what's needed and nothing more.
- // NOTE: this is NOT a common case, as preserving the backbuffer
- // is costly and usually involves copying the whole update back.
- }
+ mDirtyRegion.set(mSwapRegion.bounds());
} else {
if (flags & DisplayHardware::PARTIAL_UPDATES) {
// We need to redraw the rectangle that will be updated
@@ -864,7 +852,7 @@
}
}
- setupHardwareComposer(mDirtyRegion);
+ setupHardwareComposer();
composeSurfaces(mDirtyRegion);
// update the swap region and clear the dirty region
@@ -872,7 +860,7 @@
mDirtyRegion.clear();
}
-void SurfaceFlinger::setupHardwareComposer(Region& dirtyInOut)
+void SurfaceFlinger::setupHardwareComposer()
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
@@ -901,75 +889,8 @@
const sp<LayerBase>& layer(layers[i]);
layer->setPerFrameData(&cur[i]);
}
- const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
status_t err = hwc.prepare();
ALOGE_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 be erasing them),
- // that is, we can't erase anything outside the dirty region.
-
- Region transparent;
-
- 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);
- }
- // don't erase stuff outside the dirty region
- transparent.andSelf(dirtyInOut);
- }
-
- /*
- * clear the area of the FB that need to be transparent
- */
- if (!transparent.isEmpty()) {
- glClearColor(0,0,0,0);
- Region::const_iterator it = transparent.begin();
- Region::const_iterator const end = transparent.end();
- const int32_t height = hw.getHeight();
- while (it != end) {
- const Rect& r(*it++);
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glClear(GL_COLOR_BUFFER_BIT);
- }
- }
- }
}
void SurfaceFlinger::composeSurfaces(const Region& dirty)
@@ -978,45 +899,38 @@
HWComposer& hwc(hw.getHwComposer());
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
- if (CC_UNLIKELY(fbLayerCount && !mWormholeRegion.isEmpty())) {
- // should never happen unless the window manager has a bug
- // draw something...
- drawWormhole();
- }
+ if (fbLayerCount) {
+ // Never touch the framebuffer if we don't have any framebuffer layers
- /*
- * and then, render the layers targeted at the framebuffer
- */
+ if (!mWormholeRegion.isEmpty()) {
+ // can happen with SurfaceView
+ drawWormhole();
+ }
- hwc_layer_t* const cur(hwc.getLayers());
- const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- size_t count = layers.size();
+ /*
+ * and then, render the layers targeted at the framebuffer
+ */
+ hwc_layer_t* const cur(hwc.getLayers());
+ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const size_t count = layers.size();
- // FIXME: workaround for b/6020860
- if (hw.getFlags() & DisplayHardware::BUFFER_PRESERVED) {
for (size_t i=0 ; i<count ; i++) {
- if (cur && (cur[i].compositionType == HWC_FRAMEBUFFER)) {
- glEnable(GL_SCISSOR_TEST);
- glScissor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT);
- break;
+ const sp<LayerBase>& layer(layers[i]);
+ const Region clip(dirty.intersect(layer->visibleRegionScreen));
+ if (!clip.isEmpty()) {
+ if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
+ if ((cur[i].hints & HWC_HINT_CLEAR_FB)
+ && layer->isOpaque()) {
+ layer->clearWithOpenGL(clip);
+ }
+ continue;
+ }
+ // render the layer
+ layer->draw(clip);
}
}
}
- // FIXME: bug6020860 for b/6020860
-
-
- for (size_t i=0 ; i<count ; i++) {
- if (cur && (cur[i].compositionType != HWC_FRAMEBUFFER)) {
- continue;
- }
- const sp<LayerBase>& layer(layers[i]);
- const Region clip(dirty.intersect(layer->visibleRegionScreen));
- if (!clip.isEmpty()) {
- layer->draw(clip);
- }
- }
}
void SurfaceFlinger::debugFlashRegions()
@@ -1028,8 +942,7 @@
return;
}
- if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
- (flags & DisplayHardware::BUFFER_PRESERVED))) {
+ if (!(flags & DisplayHardware::SWAP_RECTANGLE)) {
const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
mDirtyRegion.bounds() : hw.bounds());
composeSurfaces(repaint);
@@ -1066,8 +979,6 @@
if (mDebugRegion > 1)
usleep(mDebugRegion * 1000);
-
- glEnable(GL_SCISSOR_TEST);
}
void SurfaceFlinger::drawWormhole() const
@@ -1076,52 +987,48 @@
if (region.isEmpty())
return;
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- const int32_t width = hw.getWidth();
- const int32_t height = hw.getHeight();
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_BLEND);
if (CC_LIKELY(!mDebugBackground)) {
- glClearColor(0,0,0,0);
- Region::const_iterator it = region.begin();
- Region::const_iterator const end = region.end();
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glClear(GL_COLOR_BUFFER_BIT);
- }
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(0,0,0,0);
} else {
- const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
- { width, height }, { 0, height } };
- const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } };
-
- glVertexPointer(2, GL_SHORT, 0, vertices);
- glTexCoordPointer(2, GL_SHORT, 0, tcoords);
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const int32_t width = hw.getWidth();
+ const int32_t height = hw.getHeight();
+ const GLfloat tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } };
+ glTexCoordPointer(2, GL_FLOAT, 0, tcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisable(GL_TEXTURE_EXTERNAL_OES);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
-
- glDisable(GL_BLEND);
-
glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
- Region::const_iterator it = region.begin();
- Region::const_iterator const end = region.end();
- while (it != end) {
- const Rect& r = *it++;
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_TEXTURE_2D);
- glLoadIdentity();
- glMatrixMode(GL_MODELVIEW);
}
+
+ GLfloat vertices[4][2];
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+ Region::const_iterator it = region.begin();
+ Region::const_iterator const end = region.end();
+ while (it != end) {
+ const Rect& r = *it++;
+ vertices[0][0] = r.left;
+ vertices[0][1] = r.top;
+ vertices[1][0] = r.right;
+ vertices[1][1] = r.top;
+ vertices[2][0] = r.right;
+ vertices[2][1] = r.bottom;
+ vertices[3][0] = r.left;
+ vertices[3][1] = r.bottom;
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_TEXTURE_2D);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
}
status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
@@ -1903,6 +1810,8 @@
GLuint name, tname;
glGenTextures(1, &tname);
glBindTexture(GL_TEXTURE_2D, tname);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
if (glGetError() != GL_NO_ERROR) {
@@ -1925,7 +1834,6 @@
glDisable(GL_SCISSOR_TEST);
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
- glEnable(GL_SCISSOR_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
@@ -2110,11 +2018,11 @@
}
glColorMask(1,1,1,1);
- glEnable(GL_SCISSOR_TEST);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDeleteTextures(1, &tname);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
+ glDisable(GL_SCISSOR_TEST);
return NO_ERROR;
}
@@ -2253,11 +2161,11 @@
}
glColorMask(1,1,1,1);
- glEnable(GL_SCISSOR_TEST);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDeleteTextures(1, &tname);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
+ glDisable(GL_SCISSOR_TEST);
return NO_ERROR;
}
@@ -2287,7 +2195,6 @@
glClearColor(0,0,0,1);
glDisable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
- glEnable(GL_SCISSOR_TEST);
hw.flip( Region(hw.bounds()) );
return NO_ERROR;
@@ -2425,7 +2332,6 @@
// invert everything, b/c glReadPixel() below will invert the FB
glViewport(0, 0, sw, sh);
glScissor(0, 0, sw, sh);
- glEnable(GL_SCISSOR_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -2478,7 +2384,7 @@
result = NO_MEMORY;
}
}
- glEnable(GL_SCISSOR_TEST);
+ glDisable(GL_SCISSOR_TEST);
glViewport(0, 0, hw_w, hw_h);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 46bbab2..1aea452 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -318,7 +318,7 @@
void handleWorkList();
void handleRepaint();
void postFramebuffer();
- void setupHardwareComposer(Region& dirtyInOut);
+ void setupHardwareComposer();
void composeSurfaces(const Region& dirty);
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index d7fd39e..2b647bb 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -40,10 +40,6 @@
outWidth, outHeight, outTransform);
if (err == NO_ERROR) {
switch(api) {
- case NATIVE_WINDOW_API_CPU:
- // SurfaceTextureClient supports only 2 buffers for CPU connections
- this->setBufferCountServer(2);
- break;
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
// Camera preview and videos are rate-limited on the producer