Merge "SurfaceTexture: inherit from ConsumerBase" into jb-mr1-dev
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 9765e28..65d9eb3 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -107,9 +107,11 @@
};
enum {
- eSurfaceChanged = 0x1,
- eLayerStackChanged = 0x2,
- eTransformChanged = 0x4
+ eSurfaceChanged = 0x01,
+ eLayerStackChanged = 0x02,
+ eOrientationChanged = 0x04,
+ eViewportChanged = 0x08,
+ eFrameChanged = 0x10
};
uint32_t what;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index db86d4a..1e6e1bd 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -326,7 +326,7 @@
Mutex::Autolock _l(mLock);
DisplayState& s(getDisplayStateLocked(token));
s.orientation = orientation;
- s.what |= DisplayState::eTransformChanged;
+ s.what |= DisplayState::eOrientationChanged;
mForceSynchronous = true; // TODO: do we actually still need this?
}
@@ -343,7 +343,7 @@
Mutex::Autolock _l(mLock);
DisplayState& s(getDisplayStateLocked(token));
s.viewport = viewport;
- s.what |= DisplayState::eTransformChanged;
+ s.what |= DisplayState::eViewportChanged;
}
void Composer::setDisplayFrame(const sp<IBinder>& token,
@@ -351,7 +351,7 @@
Mutex::Autolock _l(mLock);
DisplayState& s(getDisplayStateLocked(token));
s.frame = frame;
- s.what |= DisplayState::eTransformChanged;
+ s.what |= DisplayState::eFrameChanged;
}
// ---------------------------------------------------------------------------
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp
index 91b291e..3a8decc 100644
--- a/opengl/libs/GLES_trace/src/gltrace_context.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp
@@ -209,6 +209,8 @@
GLMessage_Function func = msg->function();
if (func == GLMessage::eglSwapBuffers
+ || func == GLMessage::eglCreateContext
+ || func == GLMessage::eglMakeCurrent
|| func == GLMessage::glDrawArrays
|| func == GLMessage::glDrawElements) {
mBufferedOutputStream->flush();
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 4cae692..2289444 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -140,6 +140,9 @@
mFormat = format;
mPageFlipCount = 0;
+ // external displays are always considered enabled
+ mScreenAcquired = mId >= DisplayDevice::DISPLAY_ID_COUNT;
+
// initialize the display orientation transform.
DisplayDevice::setOrientation(DisplayState::eOrientationDefault);
}
@@ -215,6 +218,18 @@
return mSecureLayerVisible;
}
+Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
+ Region dirty;
+ const Transform& planeTransform(mGlobalTransform);
+ if (repaintEverything) {
+ dirty.set(getBounds());
+ } else {
+ dirty = planeTransform.transform(this->dirtyRegion);
+ dirty.andSelf(getBounds());
+ }
+ return dirty;
+}
+
// ----------------------------------------------------------------------------
bool DisplayDevice::canDraw() const {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e9ba5ff..9790699 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -87,6 +87,7 @@
void setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const;
bool getSecureLayerVisible() const;
+ Region getDirtyRegion(bool repaintEverything) const;
status_t setOrientation(int orientation);
void setLayerStack(uint32_t stack);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index c9df7a4..a3ec352 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -334,7 +334,8 @@
}
}
-status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { // FIXME: handle multiple displays
+status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
+ // FIXME: handle multiple displays
if (uint32_t(id) >= MAX_DISPLAYS)
return BAD_INDEX;
@@ -360,6 +361,15 @@
int err = hwcPrepare(mHwc, 1,
const_cast<hwc_display_contents_1_t**>(mLists));
if (err == NO_ERROR) {
+
+ // here we're just making sure that "skip" layers are set
+ // to HWC_FRAMEBUFFER and we're also counting how many layers
+ // we have of each type.
+ // It would be nice if we could get rid of this entirely, which I
+ // think is almost possible.
+
+ // TODO: must handle multiple displays here
+
size_t numOVLayers = 0;
size_t numFBLayers = 0;
size_t count = getNumLayers(0);
@@ -397,7 +407,15 @@
return (status_t)err;
}
-size_t HWComposer::getLayerCount(int32_t id, int type) const { // FIXME: handle multiple displays
+size_t HWComposer::getLayerCount(int32_t id, int type) const {
+ // FIXME: handle multiple displays
+ if (uint32_t(id) >= MAX_DISPLAYS) {
+ // FIXME: in practice this is only use to know
+ // if we have at least one layer of type.
+ return (type == HWC_FRAMEBUFFER) ? 1 : 0;
+ }
+
+
switch (type) {
case HWC_OVERLAY:
return mNumOVLayers;
@@ -623,7 +641,11 @@
/*
* returns an iterator initialized at a given index in the layer list
*/
-HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { // FIXME: handle multiple displays
+HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) {
+ // FIXME: handle multiple displays
+ if (uint32_t(id) >= MAX_DISPLAYS)
+ return LayerListIterator();
+
if (!mHwc || index > hwcNumHwLayers(mHwc, mLists[0]))
return LayerListIterator();
if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
@@ -638,14 +660,14 @@
/*
* returns an iterator on the beginning of the layer list
*/
-HWComposer::LayerListIterator HWComposer::begin(int32_t id) { // FIXME: handle multiple displays
+HWComposer::LayerListIterator HWComposer::begin(int32_t id) {
return getLayerIterator(id, 0);
}
/*
* returns an iterator on the end of the layer list
*/
-HWComposer::LayerListIterator HWComposer::end(int32_t id) { // FIXME: handle multiple displays
+HWComposer::LayerListIterator HWComposer::end(int32_t id) {
return getLayerIterator(id, getNumLayers(id));
}
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index e6189f7..2311e6d 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -426,10 +426,10 @@
snprintf(buffer, SIZE,
" "
- "z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
+ "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
"isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
"alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
- s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
+ s.z, s.layerStack, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
s.active.crop.left, s.active.crop.top,
s.active.crop.right, s.active.crop.bottom,
isOpaque(), needsDithering(), contentDirty,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2b9ae06..c63d0cf 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -95,8 +95,7 @@
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
- mBootFinished(false),
- mExternalDisplaySurface(EGL_NO_SURFACE)
+ mBootFinished(false)
{
ALOGI("SurfaceFlinger is starting");
@@ -142,7 +141,7 @@
Vector<ComposerState> state;
Vector<DisplayState> displays;
DisplayState d;
- d.what = DisplayState::eTransformChanged;
+ d.what = DisplayState::eOrientationChanged;
d.token = mDefaultDisplays[DisplayDevice::DISPLAY_ID_MAIN];
d.orientation = DisplayState::eOrientationDefault;
displays.add(d);
@@ -555,40 +554,34 @@
return mEventThread->createEventConnection();
}
-void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) {
- EGLSurface result = EGL_NO_SURFACE;
- EGLSurface old_surface = EGL_NO_SURFACE;
- sp<SurfaceTextureClient> stc;
+void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> surface) {
- if (display != NULL) {
- stc = new SurfaceTextureClient(display);
- result = eglCreateWindowSurface(mEGLDisplay,
- mEGLConfig, (EGLNativeWindowType)stc.get(), NULL);
- ALOGE_IF(result == EGL_NO_SURFACE,
- "eglCreateWindowSurface failed (ISurfaceTexture=%p)",
- display.get());
+ sp<IBinder> token;
+ { // scope for the lock
+ Mutex::Autolock _l(mStateLock);
+ token = mExtDisplayToken;
+ }
+
+ if (token == 0) {
+ token = createDisplay();
}
{ // scope for the lock
Mutex::Autolock _l(mStateLock);
- old_surface = mExternalDisplaySurface;
- mExternalDisplayNativeWindow = stc;
- mExternalDisplaySurface = result;
- ALOGD("mExternalDisplaySurface = %p", result);
- }
+ if (surface == 0) {
+ // release our current display. we're guarantee to have
+ // a reference to it (token), while we hold the lock
+ mExtDisplayToken = 0;
+ } else {
+ mExtDisplayToken = token;
+ }
- if (old_surface != EGL_NO_SURFACE) {
- // Note: EGL allows to destroy an object while its current
- // it will fail to become current next time though.
- eglDestroySurface(mEGLDisplay, old_surface);
+ DisplayDeviceState& info(mCurrentState.displays.editValueFor(token));
+ info.surface = surface;
+ setTransactionFlags(eDisplayTransactionNeeded);
}
}
-EGLSurface SurfaceFlinger::getExternalDisplaySurface() const {
- Mutex::Autolock _l(mStateLock);
- return mExternalDisplaySurface;
-}
-
// ----------------------------------------------------------------------------
void SurfaceFlinger::waitForEvent() {
@@ -656,20 +649,101 @@
}
void SurfaceFlinger::handleMessageInvalidate() {
+ ATRACE_CALL();
handlePageFlip();
}
void SurfaceFlinger::handleMessageRefresh() {
- handleRefresh();
+ ATRACE_CALL();
+ preComposition();
+ rebuildLayerStacks();
+ setUpHWComposer();
+ doDebugFlashRegions();
+ doComposition();
+ postComposition();
+}
+void SurfaceFlinger::doDebugFlashRegions()
+{
+ // is debugging enabled
+ if (CC_LIKELY(!mDebugRegion))
+ return;
+
+ const bool repaintEverything = mRepaintEverything;
+ for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+ const sp<DisplayDevice>& hw(mDisplays[dpy]);
+ if (hw->canDraw()) {
+ // transform the dirty region into this screen's coordinate space
+ const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
+ if (!dirtyRegion.isEmpty()) {
+ // redraw the whole screen
+ doComposeSurfaces(hw, Region(hw->bounds()));
+
+ // and draw the dirty region
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glColor4f(1, 0, 1, 1);
+ const int32_t height = hw->getHeight();
+ Region::const_iterator it = dirtyRegion.begin();
+ Region::const_iterator const end = dirtyRegion.end();
+ while (it != end) {
+ const Rect& r = *it++;
+ GLfloat vertices[][2] = {
+ { r.left, height - r.top },
+ { r.left, height - r.bottom },
+ { r.right, height - r.bottom },
+ { r.right, height - r.top }
+ };
+ glVertexPointer(2, GL_FLOAT, 0, vertices);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+ hw->compositionComplete();
+ // FIXME
+ if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
+ eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
+ }
+ }
+ }
+ }
+
+ postFramebuffer();
+
+ if (mDebugRegion > 1) {
+ usleep(mDebugRegion * 1000);
+ }
+}
+
+void SurfaceFlinger::preComposition()
+{
+ bool needExtraInvalidate = false;
+ const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ if (currentLayers[i]->onPreComposition()) {
+ needExtraInvalidate = true;
+ }
+ }
+ if (needExtraInvalidate) {
+ signalLayerUpdate();
+ }
+}
+
+void SurfaceFlinger::postComposition()
+{
+ const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ currentLayers[i]->onPostComposition();
+ }
+}
+
+void SurfaceFlinger::rebuildLayerStacks() {
+ // rebuild the visible layer list per screen
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
+ ATRACE_CALL();
mVisibleRegionsDirty = false;
invalidateHwcGeometry();
-
- /*
- * rebuild the visible layer list per screen
- */
-
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
@@ -691,10 +765,13 @@
}
hw->setVisibleLayersSortedByZ(layersSortedByZ);
hw->undefinedRegion.set(hw->getBounds());
- hw->undefinedRegion.subtractSelf(hw->getTransform().transform(opaqueRegion));
+ hw->undefinedRegion.subtractSelf(
+ hw->getTransform().transform(opaqueRegion));
}
}
+}
+void SurfaceFlinger::setUpHWComposer() {
HWComposer& hwc(getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
// build the h/w work list
@@ -702,7 +779,8 @@
mHwWorkListDirty = false;
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp<const DisplayDevice> hw(mDisplays[dpy]);
- const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
+ const Vector< sp<LayerBase> >& currentLayers(
+ hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
const int32_t id = hw->getDisplayId();
@@ -730,76 +808,28 @@
status_t err = hwc.prepare();
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
}
+}
+void SurfaceFlinger::doComposition() {
+ ATRACE_CALL();
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[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());
- }
- hw->dirtyRegion.clear();
-
- if (!dirtyRegion.isEmpty()) {
- if (hw->canDraw()) {
+ if (hw->canDraw()) {
+ // transform the dirty region into this screen's coordinate space
+ const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
+ if (!dirtyRegion.isEmpty()) {
// repaint the framebuffer (if needed)
- handleRepaint(hw, dirtyRegion);
+ doDisplayComposition(hw, dirtyRegion);
}
+ hw->dirtyRegion.clear();
+ hw->flip(hw->swapRegion);
+ hw->swapRegion.clear();
}
// inform the h/w that we're done compositing
hw->compositionComplete();
}
-
postFramebuffer();
-
-
-#if 1
- // render to the external display if we have one
- EGLSurface externalDisplaySurface = getExternalDisplaySurface();
- if (externalDisplaySurface != EGL_NO_SURFACE) {
- EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
- EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
- externalDisplaySurface, externalDisplaySurface,
- eglGetCurrentContext());
-
- ALOGE_IF(!success, "eglMakeCurrent -> external failed");
-
- if (success) {
- // redraw the screen entirely...
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
- glClearColor(0,0,0,1);
- glClear(GL_COLOR_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- const sp<DisplayDevice>& hw(getDisplayDevice(0));
- const Vector< sp<LayerBase> >& layers( hw->getVisibleLayersSortedByZ() );
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer(layers[i]);
- layer->draw(hw);
- }
-
- success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
- ALOGE_IF(!success, "external display eglSwapBuffers failed");
-
- hw->compositionComplete();
- }
-
- success = eglMakeCurrent(eglGetCurrentDisplay(),
- cur, cur, eglGetCurrentContext());
-
- ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
- }
-#endif
-
}
void SurfaceFlinger::postFramebuffer()
@@ -810,26 +840,13 @@
mDebugInSwapBuffers = now;
HWComposer& hwc(getHwComposer());
-
- for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
- const sp<DisplayDevice>& hw(mDisplays[dpy]);
- if (hwc.initCheck() == NO_ERROR) {
- const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
- const size_t count = currentLayers.size();
- const int32_t id = hw->getDisplayId();
- HWComposer::LayerListIterator cur = hwc.begin(id);
- const HWComposer::LayerListIterator end = hwc.end(id);
- for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
- const sp<LayerBase>& layer(currentLayers[i]);
- layer->setAcquireFence(hw, *cur);
- }
- }
- hw->flip(hw->swapRegion);
- hw->swapRegion.clear();
- }
-
if (hwc.initCheck() == NO_ERROR) {
// FIXME: eventually commit() won't take arguments
+ // FIXME: EGL spec says:
+ // "surface must be bound to the calling thread's current context,
+ // for the current rendering API."
+ DisplayDevice::makeCurrent(
+ getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext);
hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
}
@@ -845,13 +862,10 @@
currentLayers[i]->onLayerDisplayed(hw, &*cur);
}
} else {
- eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
for (size_t i = 0; i < count; i++) {
currentLayers[i]->onLayerDisplayed(hw, NULL);
}
}
-
- // FIXME: we need to call eglSwapBuffers() on displays that have GL composition
}
mLastSwapBufferTime = systemTime() - now;
@@ -934,7 +948,7 @@
} else {
// this display is in both lists. see if something changed.
const DisplayDeviceState& state(curr[j]);
- if (state.surface != draw[i].surface) {
+ if (state.surface->asBinder() != draw[i].surface->asBinder()) {
// changing the surface is like destroying and
// recreating the DisplayDevice
@@ -967,7 +981,6 @@
// (ie: in current state but not in drawing state)
for (size_t i=0 ; i<cc ; i++) {
if (draw.indexOfKey(curr.keyAt(i)) < 0) {
- // FIXME: we need to pass the surface here
const DisplayDeviceState& state(curr[i]);
sp<SurfaceTextureClient> stc(
new SurfaceTextureClient(state.surface));
@@ -983,7 +996,8 @@
* Perform our own transaction if needed
*/
- if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
+ const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
+ if (currentLayers.size() > previousLayers.size()) {
// layers have been added
mVisibleRegionsDirty = true;
}
@@ -993,7 +1007,6 @@
if (mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
- const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
const size_t count = previousLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(previousLayers[i]);
@@ -1169,16 +1182,13 @@
void SurfaceFlinger::handlePageFlip()
{
- ATRACE_CALL();
Region dirtyRegion;
- const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
-
bool visibleRegions = false;
+ const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
const size_t count = currentLayers.size();
- sp<LayerBase> const* layers = currentLayers.array();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(layers[i]);
+ const sp<LayerBase>& layer(currentLayers[i]);
const Region dirty(layer->latchBuffer(visibleRegions));
Layer::State s(layer->drawingState());
invalidateLayerStack(s.layerStack, dirty);
@@ -1192,36 +1202,15 @@
mHwWorkListDirty = true;
}
-void SurfaceFlinger::handleRefresh()
-{
- bool needInvalidate = false;
- const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
- if (layer->onPreComposition()) {
- needInvalidate = true;
- }
- }
- if (needInvalidate) {
- signalLayerUpdate();
- }
-}
-void SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
+void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
const Region& inDirtyRegion)
{
- ATRACE_CALL();
-
Region dirtyRegion(inDirtyRegion);
// compute the invalid region
hw->swapRegion.orSelf(dirtyRegion);
- if (CC_UNLIKELY(mDebugRegion)) {
- debugFlashRegions(hw, dirtyRegion);
- }
-
uint32_t flags = hw->getFlags();
if (flags & DisplayDevice::SWAP_RECTANGLE) {
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
@@ -1242,19 +1231,24 @@
}
}
- composeSurfaces(hw, dirtyRegion);
+ doComposeSurfaces(hw, dirtyRegion);
- const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- const size_t count = currentLayers.size();
- for (size_t i=0 ; i<count ; i++) {
- currentLayers[i]->onPostComposition();
+ // FIXME: we need to call eglSwapBuffers() on displays that have
+ // GL composition and only on those.
+ // however, currently hwc.commit() already does that for the main
+ // display and never for the other ones
+ if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
+ // FIXME: EGL spec says:
+ // "surface must be bound to the calling thread's current context,
+ // for the current rendering API."
+ eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
}
// update the swap region and clear the dirty region
hw->swapRegion.orSelf(dirtyRegion);
}
-void SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
+void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
HWComposer& hwc(getHwComposer());
int32_t id = hw->getDisplayId();
@@ -1298,74 +1292,32 @@
for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
- if (!clip.isEmpty()) {
- if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
- if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
- && layer->isOpaque()) {
- // never clear the very first layer since we're
- // guaranteed the FB is already cleared
- layer->clearWithOpenGL(hw, clip);
- }
- ++cur;
- continue;
- }
- // render the layer
- layer->draw(hw, clip);
- }
if (cur != end) {
+ // we're using h/w composer
+ if (!clip.isEmpty()) {
+ if (cur->getCompositionType() == HWC_OVERLAY) {
+ if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
+ && layer->isOpaque()) {
+ // never clear the very first layer since we're
+ // guaranteed the FB is already cleared
+ layer->clearWithOpenGL(hw, clip);
+ }
+ } else {
+ layer->draw(hw, clip);
+ }
+ layer->setAcquireFence(hw, *cur);
+ }
++cur;
+ } else {
+ // we're not using h/w composer
+ if (!clip.isEmpty()) {
+ layer->draw(hw, clip);
+ }
}
}
}
}
-void SurfaceFlinger::debugFlashRegions(const sp<const DisplayDevice>& hw,
- const Region& dirtyRegion)
-{
- const uint32_t flags = hw->getFlags();
- const int32_t height = hw->getHeight();
- if (hw->swapRegion.isEmpty()) {
- return;
- }
-
- if (!(flags & DisplayDevice::SWAP_RECTANGLE)) {
- const Region repaint((flags & DisplayDevice::PARTIAL_UPDATES) ?
- dirtyRegion.bounds() : hw->bounds());
- composeSurfaces(hw, repaint);
- }
-
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- static int toggle = 0;
- toggle = 1 - toggle;
- if (toggle) {
- glColor4f(1, 0, 1, 1);
- } else {
- glColor4f(1, 1, 0, 1);
- }
-
- Region::const_iterator it = dirtyRegion.begin();
- Region::const_iterator const end = dirtyRegion.end();
- while (it != end) {
- const Rect& r = *it++;
- GLfloat vertices[][2] = {
- { r.left, height - r.top },
- { r.left, height - r.bottom },
- { r.right, height - r.bottom },
- { r.right, height - r.top }
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
-
- hw->flip(hw->swapRegion);
-
- if (mDebugRegion > 1)
- usleep(mDebugRegion * 1000);
-}
-
void SurfaceFlinger::drawWormhole(const Region& region) const
{
glDisable(GL_TEXTURE_EXTERNAL_OES);
@@ -1521,15 +1473,19 @@
flags |= eDisplayTransactionNeeded;
}
}
- if (what & DisplayState::eTransformChanged) {
+ if (what & DisplayState::eOrientationChanged) {
if (disp.orientation != s.orientation) {
disp.orientation = s.orientation;
flags |= eDisplayTransactionNeeded;
}
+ }
+ if (what & DisplayState::eFrameChanged) {
if (disp.frame != s.frame) {
disp.frame = s.frame;
flags |= eDisplayTransactionNeeded;
}
+ }
+ if (what & DisplayState::eViewportChanged) {
if (disp.viewport != s.viewport) {
disp.viewport = s.viewport;
flags |= eDisplayTransactionNeeded;
@@ -1715,7 +1671,7 @@
if (layer != 0) {
err = purgatorizeLayer_l(layer);
if (err == NO_ERROR) {
- setTransactionFlags(eDisplayTransactionNeeded);
+ setTransactionFlags(eTransactionNeeded);
}
}
return err;
@@ -1951,6 +1907,26 @@
}
/*
+ * Dump Display state
+ */
+
+ for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+ const sp<const DisplayDevice>& hw(mDisplays[dpy]);
+ snprintf(buffer, SIZE,
+ "+ DisplayDevice[%u]\n"
+ " id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, "
+ "flips=%u, secure=%d, numLayers=%u\n",
+ dpy,
+ hw->getDisplayId(), hw->getLayerStack(),
+ hw->getWidth(), hw->getHeight(),
+ hw->getOrientation(), hw->getTransform().getType(),
+ hw->getPageFlipCount(),
+ hw->getSecureLayerVisible(),
+ hw->getVisibleLayersSortedByZ().size());
+ result.append(buffer);
+ }
+
+ /*
* Dump SurfaceFlinger global state
*/
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6438bee..1f79906 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -248,9 +248,6 @@
*/
void handlePageFlip();
- void handleRefresh();
- void handleRepaint(const sp<const DisplayDevice>& hw, const Region& dirtyRegion);
-
/* ------------------------------------------------------------------------
* Transactions
*/
@@ -348,8 +345,19 @@
void computeVisibleRegions(const LayerVector& currentLayers,
uint32_t layerStack,
Region& dirtyRegion, Region& opaqueRegion);
+
+ void preComposition();
+ void postComposition();
+ void rebuildLayerStacks();
+ void setUpHWComposer();
+ void doComposition();
+ void doDebugFlashRegions();
+ void doDisplayComposition(const sp<const DisplayDevice>& hw,
+ const Region& dirtyRegion);
+ void doComposeSurfaces(const sp<const DisplayDevice>& hw,
+ const Region& dirty);
+
void postFramebuffer();
- void composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty);
void drawWormhole(const Region& region) const;
GLuint getProtectedTexName() const {
return mProtectedTexName;
@@ -358,7 +366,6 @@
/* ------------------------------------------------------------------------
* Debugging & dumpsys
*/
- void debugFlashRegions(const sp<const DisplayDevice>& hw, const Region& dirtyReg);
void listLayersLocked(const Vector<String16>& args, size_t& index,
String8& result, char* buffer, size_t SIZE) const;
void dumpStatsLocked(const Vector<String16>& args, size_t& index,
@@ -428,9 +435,7 @@
* Feature prototyping
*/
- EGLSurface getExternalDisplaySurface() const;
- sp<SurfaceTextureClient> mExternalDisplayNativeWindow;
- EGLSurface mExternalDisplaySurface;
+ sp<IBinder> mExtDisplayToken;
};
// ---------------------------------------------------------------------------