Merge "Add Thread::isRunning and Condition::signal(WakeUpType)" into jb-mr2-dev
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index fd390f5..d081590 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -31,6 +31,7 @@
#include <sys/klog.h>
#include <time.h>
#include <unistd.h>
+#include <sys/prctl.h>
#include <cutils/debugger.h>
#include <cutils/properties.h>
@@ -264,6 +265,9 @@
const char *args[1024] = {command};
size_t arg;
+ /* make sure the child dies when dumpstate dies */
+ prctl(PR_SET_PDEATHSIG, SIGKILL);
+
va_list ap;
va_start(ap, command);
if (title) printf("------ %s (%s", title, command);
diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
index 28e58e4..ce7fde0 100644
--- a/cmds/surfaceflinger/main_surfaceflinger.cpp
+++ b/cmds/surfaceflinger/main_surfaceflinger.cpp
@@ -20,9 +20,9 @@
using namespace android;
int main(int argc, char** argv) {
- SurfaceFlinger::publishAndJoinThreadPool(true);
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
+ SurfaceFlinger::publishAndJoinThreadPool(true);
return 0;
}
diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h
index 6460268..5ac36d9 100644
--- a/include/binder/BinderService.h
+++ b/include/binder/BinderService.h
@@ -36,13 +36,18 @@
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
- return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
+ return sm->addService(
+ String16(SERVICE::getServiceName()),
+ new SERVICE(), allowIsolated);
}
static void publishAndJoinThreadPool(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
- sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
+ sm->addService(
+ String16(SERVICE::getServiceName()),
+ new SERVICE(), allowIsolated);
ProcessState::self()->startThreadPool();
+ ProcessState::self()->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
}
diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h
index 8caf1af..e63a0d0 100644
--- a/include/binder/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -71,6 +71,7 @@
void spawnPooledThread(bool isMain);
status_t setThreadPoolMaxThreadCount(size_t maxThreads);
+ void giveThreadPoolName();
private:
friend class IPCThreadState;
@@ -80,6 +81,7 @@
ProcessState(const ProcessState& o);
ProcessState& operator=(const ProcessState& o);
+ String8 makeBinderThreadName();
struct handle_entry {
IBinder* binder;
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index 23d1d4c..4afc860 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -48,9 +48,7 @@
eProtectedByDRM = 0x00001000,
eFXSurfaceNormal = 0x00000000,
- eFXSurfaceBlur = 0x00010000, // deprecated, same as Dim
eFXSurfaceDim = 0x00020000,
- eFXSurfaceScreenshot= 0x00030000,
eFXSurfaceMask = 0x000F0000,
};
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 4b9b5a8..ea9368d 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -24,6 +24,7 @@
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <utils/Flattenable.h>
+#include <utils/RefBase.h>
struct ANativeWindowBuffer;
@@ -37,10 +38,8 @@
// ===========================================================================
class GraphicBuffer
- : public ANativeObjectBase<
- ANativeWindowBuffer,
- GraphicBuffer,
- LightRefBase<GraphicBuffer> >, public Flattenable
+ : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,
+ public Flattenable
{
public:
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h
index f67648f..4eee14d 100644
--- a/include/utils/AndroidThreads.h
+++ b/include/utils/AndroidThreads.h
@@ -56,6 +56,9 @@
size_t threadStackSize,
android_thread_id_t *threadId);
+// set the same of the running thread
+extern void androidSetThreadName(const char* name);
+
// Used by the Java Runtime to control how threads are created, so that
// they can be proper and lovely Java threads.
typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index d95fd6f..294e1d4 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -283,15 +283,20 @@
}
}
+String8 ProcessState::makeBinderThreadName() {
+ int32_t s = android_atomic_add(1, &mThreadPoolSeq);
+ String8 name;
+ name.appendFormat("Binder_%X", s);
+ return name;
+}
+
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
- int32_t s = android_atomic_add(1, &mThreadPoolSeq);
- char buf[16];
- snprintf(buf, sizeof(buf), "Binder_%X", s);
- ALOGV("Spawning new pooled thread, name=%s\n", buf);
+ String8 name = makeBinderThreadName();
+ ALOGV("Spawning new pooled thread, name=%s\n", name.string());
sp<Thread> t = new PoolThread(isMain);
- t->run(buf);
+ t->run(name.string());
}
}
@@ -304,6 +309,10 @@
return result;
}
+void ProcessState::giveThreadPoolName() {
+ androidSetThreadName( makeBinderThreadName().string() );
+}
+
static int open_driver()
{
int fd = open("/dev/binder", O_RDWR);
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index fbaf6aa..2d30305 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1636,6 +1636,81 @@
}
}
+TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentBeforeConsumerDeathUnrefsBuffers) {
+ sp<GraphicBuffer> buffer;
+
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+
+ // Produce a frame
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ // Destroy the EGLSurface.
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ mProducerEglSurface = EGL_NO_SURFACE;
+ mSTC.clear();
+ mANW.clear();
+ mTextureRenderer.clear();
+
+ // Consume a frame
+ ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+ buffer = mST->getCurrentBuffer();
+
+ // Destroy the GL texture object to release its ref
+ GLuint texID = TEX_ID;
+ glDeleteTextures(1, &texID);
+
+ // make un-current, all references to buffer should be gone
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+ // Destroy consumer
+ mST.clear();
+
+ EXPECT_EQ(1, buffer->getStrongCount());
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers) {
+ sp<GraphicBuffer> buffer;
+
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+ mProducerEglSurface, mProducerEglContext));
+
+ // Produce a frame
+ glClear(GL_COLOR_BUFFER_BIT);
+ EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+ // Destroy the EGLSurface.
+ EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+ ASSERT_EQ(EGL_SUCCESS, eglGetError());
+ mProducerEglSurface = EGL_NO_SURFACE;
+ mSTC.clear();
+ mANW.clear();
+ mTextureRenderer.clear();
+
+ // Consume a frame
+ ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+ buffer = mST->getCurrentBuffer();
+
+ // Destroy the GL texture object to release its ref
+ GLuint texID = TEX_ID;
+ glDeleteTextures(1, &texID);
+
+ // Destroy consumer
+ mST.clear();
+
+ // make un-current, all references to buffer should be gone
+ EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
+ EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+ EXPECT_EQ(1, buffer->getStrongCount());
+}
+
+
TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
// This test requires 3 buffers to run on a single thread.
mST->setDefaultMaxBufferCount(3);
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index e80a795..2b39bce 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -199,7 +199,7 @@
{
char name[100];
snprintf(name, 100, "/data/%p.stack", this);
- int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
+ int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
if (rc >= 0) {
write(rc, text.string(), text.length());
close(rc);
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 1d61457..7b877e0 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -109,30 +109,34 @@
}
if (name) {
-#if defined(HAVE_PRCTL)
- // Mac OS doesn't have this, and we build libutil for the host too
- int hasAt = 0;
- int hasDot = 0;
- char *s = name;
- while (*s) {
- if (*s == '.') hasDot = 1;
- else if (*s == '@') hasAt = 1;
- s++;
- }
- int len = s - name;
- if (len < 15 || hasAt || !hasDot) {
- s = name;
- } else {
- s = name + len - 15;
- }
- prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
-#endif
+ androidSetThreadName(name);
free(name);
}
return f(u);
}
};
+void androidSetThreadName(const char* name) {
+#if defined(HAVE_PRCTL)
+ // Mac OS doesn't have this, and we build libutil for the host too
+ int hasAt = 0;
+ int hasDot = 0;
+ const char *s = name;
+ while (*s) {
+ if (*s == '.') hasDot = 1;
+ else if (*s == '@') hasAt = 1;
+ s++;
+ }
+ int len = s - name;
+ if (len < 15 || hasAt || !hasDot) {
+ s = name;
+ } else {
+ s = name + len - 15;
+ }
+ prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
+#endif
+}
+
int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
void *userData,
const char* threadName,
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 172ef95..0ed5727 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -147,6 +147,7 @@
EGLDisplay dpy;
EGLConfig config;
EGLContext ctx;
+ bool zombie;
egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
virtual ~egl_surface_t();
@@ -173,7 +174,7 @@
egl_surface_t::egl_surface_t(EGLDisplay dpy,
EGLConfig config,
int32_t depthFormat)
- : magic(MAGIC), dpy(dpy), config(config), ctx(0)
+ : magic(MAGIC), dpy(dpy), config(config), ctx(0), zombie(false)
{
depth.version = sizeof(GGLSurface);
depth.data = 0;
@@ -419,9 +420,8 @@
bits = NULL;
unlock(buffer);
}
- // enqueue the last frame
- nativeWindow->queueBuffer(nativeWindow, buffer, -1);
if (buffer) {
+ nativeWindow->cancelBuffer(nativeWindow, buffer, -1);
buffer->common.decRef(&buffer->common);
buffer = 0;
}
@@ -1580,11 +1580,12 @@
if (surface->dpy != dpy)
return setError(EGL_BAD_DISPLAY, EGL_FALSE);
if (surface->ctx) {
- // FIXME: this surface is current check what the spec says
+ // defer disconnect/delete until no longer current
+ surface->zombie = true;
+ } else {
surface->disconnect();
- surface->ctx = 0;
+ delete surface;
}
- delete surface;
}
return EGL_TRUE;
}
@@ -1736,6 +1737,9 @@
if (c->draw) {
egl_surface_t* s = reinterpret_cast<egl_surface_t*>(c->draw);
s->disconnect();
+ s->ctx = EGL_NO_CONTEXT;
+ if (s->zombie)
+ delete s;
}
if (c->read) {
// FIXME: unlock/disconnect the read surface too
@@ -1777,8 +1781,10 @@
egl_surface_t* r = (egl_surface_t*)c->read;
if (d) {
c->draw = 0;
- d->ctx = EGL_NO_CONTEXT;
d->disconnect();
+ d->ctx = EGL_NO_CONTEXT;
+ if (d->zombie)
+ delete d;
}
if (r) {
c->read = 0;
diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk
index 7d43759..bb3cc0c 100644
--- a/opengl/tests/gl2_yuvtex/Android.mk
+++ b/opengl/tests/gl2_yuvtex/Android.mk
@@ -5,9 +5,10 @@
gl2_yuvtex.cpp
LOCAL_SHARED_LIBRARIES := \
- libcutils \
+ libcutils \
libEGL \
libGLESv2 \
+ libutils \
libui
LOCAL_C_INCLUDES += $(call include-path-for, opengl-tests-includes)
diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk
index 9e5dba0..e0e2c16 100644
--- a/opengl/tests/gl_yuvtex/Android.mk
+++ b/opengl/tests/gl_yuvtex/Android.mk
@@ -5,9 +5,10 @@
gl_yuvtex.cpp
LOCAL_SHARED_LIBRARIES := \
- libcutils \
+ libcutils \
libEGL \
libGLESv1_CM \
+ libutils \
libui
LOCAL_C_INCLUDES += $(call include-path-for, opengl-tests-includes)
diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
index 9eb58b1..177eb63 100644
--- a/opengl/tests/hwc/Android.mk
+++ b/opengl/tests/hwc/Android.mk
@@ -39,6 +39,7 @@
libcutils \
libEGL \
libGLESv2 \
+ libutils \
libui \
libhardware \
@@ -70,6 +71,7 @@
libcutils \
libEGL \
libGLESv2 \
+ libutils \
libui \
libhardware \
@@ -99,6 +101,7 @@
libcutils \
libEGL \
libGLESv2 \
+ libutils \
libui \
libhardware \
@@ -128,6 +131,7 @@
libcutils \
libEGL \
libGLESv2 \
+ libutils \
libui \
libhardware \
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index b4b19b4..5ff8154 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -7,9 +7,7 @@
EventThread.cpp \
FrameTracker.cpp \
Layer.cpp \
- LayerBase.cpp \
LayerDim.cpp \
- LayerScreenshot.cpp \
DisplayHardware/FramebufferSurface.cpp \
DisplayHardware/HWComposer.cpp \
DisplayHardware/PowerHAL.cpp \
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0f56f99..0575e35 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -23,7 +23,6 @@
#include "Client.h"
#include "Layer.h"
-#include "LayerBase.h"
#include "SurfaceFlinger.h"
namespace android {
@@ -43,7 +42,7 @@
{
const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) {
- sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
+ sp<Layer> layer(mLayers.valueAt(i).promote());
if (layer != 0) {
mFlinger->removeLayer(layer);
}
@@ -54,13 +53,13 @@
return NO_ERROR;
}
-void Client::attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer)
+void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
{
Mutex::Autolock _l(mLock);
mLayers.add(handle, layer);
}
-void Client::detachLayer(const LayerBaseClient* layer)
+void Client::detachLayer(const Layer* layer)
{
Mutex::Autolock _l(mLock);
// we do a linear search here, because this doesn't happen often
@@ -72,11 +71,11 @@
}
}
}
-sp<LayerBaseClient> Client::getLayerUser(const sp<IBinder>& handle) const
+sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
{
Mutex::Autolock _l(mLock);
- sp<LayerBaseClient> lbc;
- wp<LayerBaseClient> layer(mLayers.valueFor(handle));
+ sp<Layer> lbc;
+ wp<Layer> layer(mLayers.valueFor(handle));
if (layer != 0) {
lbc = layer.promote();
ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index e6a7165..4f34b86 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -30,7 +30,7 @@
// ---------------------------------------------------------------------------
-class LayerBaseClient;
+class Layer;
class SurfaceFlinger;
// ---------------------------------------------------------------------------
@@ -44,11 +44,11 @@
status_t initCheck() const;
// protected by SurfaceFlinger::mStateLock
- void attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer);
+ void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
- void detachLayer(const LayerBaseClient* layer);
+ void detachLayer(const Layer* layer);
- sp<LayerBaseClient> getLayerUser(const sp<IBinder>& handle) const;
+ sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
private:
// ISurfaceComposerClient interface
@@ -66,7 +66,7 @@
sp<SurfaceFlinger> mFlinger;
// protected by mLock
- DefaultKeyedVector< wp<IBinder>, wp<LayerBaseClient> > mLayers;
+ DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
// thread-safe
mutable Mutex mLock;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index ed2768c..2bbe49c 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -42,7 +42,7 @@
#include "DisplayDevice.h"
#include "GLExtensions.h"
#include "SurfaceFlinger.h"
-#include "LayerBase.h"
+#include "Layer.h"
// ----------------------------------------------------------------------------
using namespace android;
@@ -282,19 +282,19 @@
// ----------------------------------------------------------------------------
-void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
+void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
mVisibleLayersSortedByZ = layers;
mSecureLayerVisible = false;
size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(layers[i]);
+ const sp<Layer>& layer(layers[i]);
if (layer->isSecure()) {
mSecureLayerVisible = true;
}
}
}
-const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const {
+const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
return mVisibleLayersSortedByZ;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 91f34db..f671017 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -38,7 +38,7 @@
class DisplayInfo;
class FramebufferSurface;
-class LayerBase;
+class Layer;
class SurfaceFlinger;
class HWComposer;
@@ -99,8 +99,8 @@
EGLSurface getEGLSurface() const;
- void setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
- const Vector< sp<LayerBase> >& getVisibleLayersSortedByZ() const;
+ void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers);
+ const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const;
bool getSecureLayerVisible() const;
Region getDirtyRegion(bool repaintEverything) const;
@@ -186,7 +186,7 @@
*/
// list of visible layers on that display
- Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
+ Vector< sp<Layer> > mVisibleLayersSortedByZ;
// Whether we have a visible secure layer on this display
bool mSecureLayerVisible;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 11f65f6..bb567e2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -41,7 +41,6 @@
#include <cutils/properties.h>
#include "Layer.h" // needed only for debugging
-#include "LayerBase.h"
#include "HWComposer.h"
#include "SurfaceFlinger.h"
#include <utils/CallStack.h>
@@ -925,7 +924,7 @@
for (size_t i=0 ; i<mNumDisplays ; i++) {
const DisplayData& disp(mDisplayData[i]);
- const Vector< sp<LayerBase> >& visibleLayersSortedByZ =
+ const Vector< sp<Layer> >& visibleLayersSortedByZ =
mFlinger->getLayerSortedByZForHwcDisplay(i);
if (disp.connected) {
@@ -949,13 +948,11 @@
String8 name("unknown");
if (i < visibleLayersSortedByZ.size()) {
- const sp<LayerBase>& layer(visibleLayersSortedByZ[i]);
- if (layer->getLayer() != NULL) {
- const sp<GraphicBuffer>& buffer(
- layer->getLayer()->getActiveBuffer());
- if (buffer != NULL) {
- format = buffer->getPixelFormat();
- }
+ const sp<Layer>& layer(visibleLayersSortedByZ[i]);
+ const sp<GraphicBuffer>& buffer(
+ layer->getActiveBuffer());
+ if (buffer != NULL) {
+ format = buffer->getPixelFormat();
}
name = layer->getName();
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index f7ed1aa..9816a45 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -47,7 +47,6 @@
class GraphicBuffer;
class Fence;
-class LayerBase;
class Region;
class String8;
class SurfaceFlinger;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c9f1eb5..44ef0b8 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
+#include <math.h>
#include <cutils/compiler.h>
#include <cutils/native_handle.h>
@@ -49,37 +50,39 @@
// ---------------------------------------------------------------------------
+int32_t Layer::sSequence = 1;
+
Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
- : LayerBaseClient(flinger, client),
+ : contentDirty(false),
+ sequence(uint32_t(android_atomic_inc(&sSequence))),
+ mFlinger(flinger),
mTextureName(-1U),
+ mPremultipliedAlpha(true),
+ mName("unnamed"),
+ mDebug(false),
+ mFormat(PIXEL_FORMAT_NONE),
+ mGLExtensions(GLExtensions::getInstance()),
+ mOpaqueLayer(true),
+ mTransactionFlags(0),
mQueuedFrames(0),
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
mRefreshPending(false),
mFrameLatencyNeeded(false),
- mFormat(PIXEL_FORMAT_NONE),
- mGLExtensions(GLExtensions::getInstance()),
- mOpaqueLayer(true),
+ mFiltering(false),
+ mNeedsFiltering(false),
mSecure(false),
- mProtectedByApp(false)
+ mProtectedByApp(false),
+ mHasSurface(false),
+ mClientRef(client)
{
mCurrentCrop.makeInvalid();
glGenTextures(1, &mTextureName);
}
-void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface* layer) {
- LayerBaseClient::onLayerDisplayed(hw, layer);
- if (layer) {
- mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
- }
-}
-
void Layer::onFirstRef()
{
- LayerBaseClient::onFirstRef();
-
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<BufferQueue> bq = new SurfaceTextureLayer();
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
@@ -102,9 +105,25 @@
Layer::~Layer()
{
+ sp<Client> c(mClientRef.promote());
+ if (c != 0) {
+ c->detachLayer(this);
+ }
mFlinger->deleteTextureAsync(mTextureName);
}
+// ---------------------------------------------------------------------------
+// callbacks
+// ---------------------------------------------------------------------------
+
+void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface* layer) {
+ if (layer) {
+ layer->onDisplayed();
+ mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
+ }
+}
+
void Layer::onFrameAvailable() {
android_atomic_inc(&mQueuedFrames);
mFlinger->signalLayerUpdate();
@@ -112,56 +131,45 @@
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// in the purgatory list
-void Layer::onRemoved()
-{
+void Layer::onRemoved() {
mSurfaceFlingerConsumer->abandon();
}
+// ---------------------------------------------------------------------------
+// set-up
+// ---------------------------------------------------------------------------
+
void Layer::setName(const String8& name) {
- LayerBase::setName(name);
+ mName = name;
mSurfaceFlingerConsumer->setName(name);
}
-sp<ISurface> Layer::createSurface()
-{
- /*
- * This class provides an implementation of BnSurface (the "native" or
- * "remote" side of the Binder IPC interface ISurface), and mixes in
- * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
- * this layer when the BSurface is destroyed.
- *
- * The idea is to provide a handle to the Layer through ISurface that
- * is cleaned up automatically when the last reference to the ISurface
- * goes away. (The references will be held on the "proxy" side, while
- * the Layer exists on the "native" side.)
- *
- * The Layer has a reference to an instance of SurfaceFlinger's variant
- * of GLConsumer, which holds a reference to the BufferQueue. The
- * getSurfaceTexture() call returns a Binder interface reference for
- * the producer interface of the buffer queue associated with the Layer.
- */
- class BSurface : public BnSurface, public LayerCleaner {
- wp<const Layer> mOwner;
- virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
- sp<IGraphicBufferProducer> res;
- sp<const Layer> that( mOwner.promote() );
- if (that != NULL) {
- res = that->mSurfaceFlingerConsumer->getBufferQueue();
- }
- return res;
- }
- public:
- BSurface(const sp<SurfaceFlinger>& flinger,
- const sp<Layer>& layer)
- : LayerCleaner(flinger, layer), mOwner(layer) { }
- };
- sp<ISurface> sur(new BSurface(mFlinger, this));
- return sur;
+String8 Layer::getName() const {
+ return mName;
}
-wp<IBinder> Layer::getSurfaceTextureBinder() const
+void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
{
- return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
+ uint32_t layerFlags = 0;
+ if (flags & ISurfaceComposerClient::eHidden)
+ layerFlags = layer_state_t::eLayerHidden;
+
+ if (flags & ISurfaceComposerClient::eNonPremultiplied)
+ mPremultipliedAlpha = false;
+
+ mCurrentState.active.w = w;
+ mCurrentState.active.h = h;
+ mCurrentState.active.crop.makeInvalid();
+ mCurrentState.z = 0;
+ mCurrentState.alpha = 0xFF;
+ mCurrentState.layerStack = 0;
+ mCurrentState.flags = layerFlags;
+ mCurrentState.sequence = 0;
+ mCurrentState.transform.set(0, 0);
+ mCurrentState.requested = mCurrentState.active;
+
+ // drawing state & current state are identical
+ mDrawingState = mCurrentState;
}
status_t Layer::setBuffers( uint32_t w, uint32_t h,
@@ -199,6 +207,63 @@
return NO_ERROR;
}
+sp<ISurface> Layer::createSurface() {
+ /*
+ * This class provides an implementation of BnSurface (the "native" or
+ * "remote" side of the Binder IPC interface ISurface), and mixes in
+ * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
+ * this layer when the BSurface is destroyed.
+ *
+ * The idea is to provide a handle to the Layer through ISurface that
+ * is cleaned up automatically when the last reference to the ISurface
+ * goes away. (The references will be held on the "proxy" side, while
+ * the Layer exists on the "native" side.)
+ *
+ * The Layer has a reference to an instance of SurfaceFlinger's variant
+ * of GLConsumer, which holds a reference to the BufferQueue. The
+ * getSurfaceTexture() call returns a Binder interface reference for
+ * the producer interface of the buffer queue associated with the Layer.
+ */
+ class BSurface : public BnSurface, public LayerCleaner {
+ wp<const Layer> mOwner;
+ virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
+ sp<IGraphicBufferProducer> res;
+ sp<const Layer> that( mOwner.promote() );
+ if (that != NULL) {
+ res = that->mSurfaceFlingerConsumer->getBufferQueue();
+ }
+ return res;
+ }
+ public:
+ BSurface(const sp<SurfaceFlinger>& flinger,
+ const sp<Layer>& layer)
+ : LayerCleaner(flinger, layer), mOwner(layer) { }
+ };
+ sp<ISurface> sur(new BSurface(mFlinger, this));
+ return sur;
+}
+
+wp<IBinder> Layer::getSurfaceTextureBinder() const {
+ return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
+}
+
+sp<ISurface> Layer::getSurface()
+{
+ sp<ISurface> s;
+ Mutex::Autolock _l(mLock);
+
+ LOG_ALWAYS_FATAL_IF(mHasSurface,
+ "Layer::getSurface() has already been called");
+
+ mHasSurface = true;
+ s = createSurface();
+ return s;
+}
+
+// ---------------------------------------------------------------------------
+// h/w composer set-up
+// ---------------------------------------------------------------------------
+
Rect Layer::getContentCrop() const {
// this is the crop rectangle that applies to the buffer
// itself (as opposed to the window)
@@ -220,11 +285,85 @@
return mCurrentTransform;
}
+Rect Layer::computeBounds() const {
+ const Layer::State& s(drawingState());
+ Rect win(s.active.w, s.active.h);
+ if (!s.active.crop.isEmpty()) {
+ win.intersect(s.active.crop, &win);
+ }
+ return win;
+}
+
+Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
+ /*
+ * The way we compute the crop (aka. texture coordinates when we have a
+ * Layer) produces a different output from the GL code in
+ * drawWithOpenGL() due to HWC being limited to integers. The difference
+ * can be large if getContentTransform() contains a large scale factor.
+ * See comments in drawWithOpenGL() for more details.
+ */
+
+ // the content crop is the area of the content that gets scaled to the
+ // layer's size.
+ Rect crop(getContentCrop());
+
+ // the active.crop is the area of the window that gets cropped, but not
+ // scaled in any ways.
+ const State& s(drawingState());
+
+ // apply the projection's clipping to the window crop in
+ // layerstack space, and convert-back to layer space.
+ // if there are no window scaling (or content scaling) involved,
+ // this operation will map to full pixels in the buffer.
+ // NOTE: should we revert to GL composition if a scaling is involved
+ // since it cannot be represented in the HWC API?
+ Rect activeCrop(s.transform.transform(s.active.crop));
+ activeCrop.intersect(hw->getViewport(), &activeCrop);
+ activeCrop = s.transform.inverse().transform(activeCrop);
+
+ // paranoia: make sure the window-crop is constrained in the
+ // window's bounds
+ activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
+
+ if (!activeCrop.isEmpty()) {
+ // Transform the window crop to match the buffer coordinate system,
+ // which means using the inverse of the current transform set on the
+ // SurfaceFlingerConsumer.
+ uint32_t invTransform = getContentTransform();
+ int winWidth = s.active.w;
+ int winHeight = s.active.h;
+ if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+ NATIVE_WINDOW_TRANSFORM_FLIP_H;
+ winWidth = s.active.h;
+ winHeight = s.active.w;
+ }
+ const Rect winCrop = activeCrop.transform(
+ invTransform, s.active.w, s.active.h);
+
+ // the code below essentially performs a scaled intersection
+ // of crop and winCrop
+ float xScale = float(crop.width()) / float(winWidth);
+ float yScale = float(crop.height()) / float(winHeight);
+
+ int insetL = int(ceilf( winCrop.left * xScale));
+ int insetT = int(ceilf( winCrop.top * yScale));
+ int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
+ int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
+
+ crop.left += insetL;
+ crop.top += insetT;
+ crop.right -= insetR;
+ crop.bottom -= insetB;
+ }
+ return crop;
+}
+
void Layer::setGeometry(
const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer)
{
- LayerBaseClient::setGeometry(hw, layer);
+ layer.setDefaultState();
// enable this layer
layer.setSkip(false);
@@ -233,7 +372,21 @@
layer.setSkip(true);
}
+ // this gives us only the "orientation" component of the transform
const State& s(drawingState());
+ if (!isOpaque() || s.alpha != 0xFF) {
+ layer.setBlending(mPremultipliedAlpha ?
+ HWC_BLENDING_PREMULT :
+ HWC_BLENDING_COVERAGE);
+ }
+
+ // apply the layer's transform, followed by the display's global transform
+ // here we're guaranteed that the layer's transform preserves rects
+ Rect frame(s.transform.transform(computeBounds()));
+ frame.intersect(hw->getViewport(), &frame);
+ const Transform& tr(hw->getTransform());
+ layer.setFrame(tr.transform(frame));
+ layer.setCrop(computeCrop(hw));
layer.setPlaneAlpha(s.alpha);
/*
@@ -245,22 +398,29 @@
*/
const Transform bufferOrientation(mCurrentTransform);
- const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
+ const Transform transform(tr * s.transform * bufferOrientation);
// this gives us only the "orientation" component of the transform
- const uint32_t finalTransform = tr.getOrientation();
-
- // we can only handle simple transformation
- if (finalTransform & Transform::ROT_INVALID) {
+ const uint32_t orientation = transform.getOrientation();
+ if (orientation & Transform::ROT_INVALID) {
+ // we can only handle simple transformation
layer.setSkip(true);
} else {
- layer.setTransform(finalTransform);
+ layer.setTransform(orientation);
}
}
void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer) {
- LayerBaseClient::setPerFrameData(hw, layer);
+ // we have to set the visible region on every frame because
+ // we currently free it during onLayerDisplayed(), which is called
+ // after HWComposer::commit() -- every frame.
+ // Apply this display's projection's viewport to the visible region
+ // before giving it to the HWC HAL.
+ const Transform& tr = hw->getTransform();
+ Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
+ layer.setVisibleRegionScreen(visible);
+
// NOTE: buffer can be NULL if the client never drew into this
// layer yet, or if we ran out of memory
layer.setBuffer(mActiveBuffer);
@@ -285,6 +445,18 @@
layer.setAcquireFenceFd(fenceFd);
}
+// ---------------------------------------------------------------------------
+// drawing...
+// ---------------------------------------------------------------------------
+
+void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
+ onDraw(hw, clip);
+}
+
+void Layer::draw(const sp<const DisplayDevice>& hw) {
+ onDraw( hw, Region(hw->bounds()) );
+}
+
void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
{
ATRACE_CALL();
@@ -304,8 +476,8 @@
mFlinger->mDrawingState.layersSortedByZ);
const size_t count = drawingLayers.size();
for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer(drawingLayers[i]);
- if (layer.get() == static_cast<LayerBase const*>(this))
+ const sp<Layer>& layer(drawingLayers[i]);
+ if (layer.get() == static_cast<Layer const*>(this))
break;
under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
}
@@ -365,6 +537,119 @@
glDisable(GL_TEXTURE_2D);
}
+
+void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
+ GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
+{
+ const uint32_t fbHeight = hw->getHeight();
+ glColor4f(red,green,blue,alpha);
+
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ LayerMesh mesh;
+ computeGeometry(hw, &mesh);
+
+ glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
+}
+
+void Layer::clearWithOpenGL(
+ const sp<const DisplayDevice>& hw, const Region& clip) const {
+ clearWithOpenGL(hw, clip, 0,0,0,0);
+}
+
+void Layer::drawWithOpenGL(
+ const sp<const DisplayDevice>& hw, const Region& clip) const {
+ const uint32_t fbHeight = hw->getHeight();
+ const State& s(drawingState());
+
+ GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+ if (CC_UNLIKELY(s.alpha < 0xFF)) {
+ const GLfloat alpha = s.alpha * (1.0f/255.0f);
+ if (mPremultipliedAlpha) {
+ glColor4f(alpha, alpha, alpha, alpha);
+ } else {
+ glColor4f(1, 1, 1, alpha);
+ }
+ glEnable(GL_BLEND);
+ glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ } else {
+ glColor4f(1, 1, 1, 1);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ if (!isOpaque()) {
+ glEnable(GL_BLEND);
+ glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glDisable(GL_BLEND);
+ }
+ }
+
+ LayerMesh mesh;
+ computeGeometry(hw, &mesh);
+
+ // TODO: we probably want to generate the texture coords with the mesh
+ // here we assume that we only have 4 vertices
+
+ struct TexCoords {
+ GLfloat u;
+ GLfloat v;
+ };
+
+
+ /*
+ * NOTE: the way we compute the texture coordinates here produces
+ * different results than when we take the HWC path -- in the later case
+ * the "source crop" is rounded to texel boundaries.
+ * This can produce significantly different results when the texture
+ * is scaled by a large amount.
+ *
+ * The GL code below is more logical (imho), and the difference with
+ * HWC is due to a limitation of the HWC API to integers -- a question
+ * is suspend is wether we should ignore this problem or revert to
+ * GL composition when a buffer scaling is applied (maybe with some
+ * minimal value)? Or, we could make GL behave like HWC -- but this feel
+ * like more of a hack.
+ */
+ const Rect win(computeBounds());
+
+ GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
+ GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
+ GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
+ GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
+
+ TexCoords texCoords[4];
+ texCoords[0].u = left;
+ texCoords[0].v = top;
+ texCoords[1].u = left;
+ texCoords[1].v = bottom;
+ texCoords[2].u = right;
+ texCoords[2].v = bottom;
+ texCoords[3].u = right;
+ texCoords[3].v = top;
+ for (int i = 0; i < 4; i++) {
+ texCoords[i].v = 1.0f - texCoords[i].v;
+ }
+
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+ glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_BLEND);
+}
+
+void Layer::setFiltering(bool filtering) {
+ mFiltering = filtering;
+}
+
+bool Layer::getFiltering() const {
+ return mFiltering;
+}
+
// As documented in libhardware header, formats in the range
// 0x100 - 0x1FF are specific to the HAL implementation, and
// are known to have no alpha channel
@@ -383,6 +668,29 @@
return (err || info.h_alpha <= info.l_alpha);
}
+// ----------------------------------------------------------------------------
+// local state
+// ----------------------------------------------------------------------------
+
+void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
+{
+ const Layer::State& s(drawingState());
+ const Transform tr(hw->getTransform() * s.transform);
+ const uint32_t hw_h = hw->getHeight();
+ Rect win(s.active.w, s.active.h);
+ if (!s.active.crop.isEmpty()) {
+ win.intersect(s.active.crop, &win);
+ }
+ if (mesh) {
+ tr.transform(mesh->mVertices[0], win.left, win.top);
+ tr.transform(mesh->mVertices[1], win.left, win.bottom);
+ tr.transform(mesh->mVertices[2], win.right, win.bottom);
+ tr.transform(mesh->mVertices[3], win.right, win.top);
+ for (size_t i=0 ; i<4 ; i++) {
+ mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
+ }
+ }
+}
bool Layer::isOpaque() const
{
@@ -404,8 +712,39 @@
(activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
}
-uint32_t Layer::doTransaction(uint32_t flags)
-{
+bool Layer::isFixedSize() const {
+ return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
+}
+
+bool Layer::isCropped() const {
+ return !mCurrentCrop.isEmpty();
+}
+
+bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
+ return mNeedsFiltering || hw->needsFiltering();
+}
+
+void Layer::setVisibleRegion(const Region& visibleRegion) {
+ // always called from main thread
+ this->visibleRegion = visibleRegion;
+}
+
+void Layer::setCoveredRegion(const Region& coveredRegion) {
+ // always called from main thread
+ this->coveredRegion = coveredRegion;
+}
+
+void Layer::setVisibleNonTransparentRegion(const Region&
+ setVisibleNonTransparentRegion) {
+ // always called from main thread
+ this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
+}
+
+// ----------------------------------------------------------------------------
+// transaction
+// ----------------------------------------------------------------------------
+
+uint32_t Layer::doTransaction(uint32_t flags) {
ATRACE_CALL();
const Layer::State& front(drawingState());
@@ -464,7 +803,7 @@
(temp.requested.h != temp.active.h);
if (resizePending) {
- // don't let LayerBase::doTransaction update the drawing state
+ // don't let Layer::doTransaction update the drawing state
// if we have a pending resize, unless we are in fixed-size mode.
// the drawing state will be updated only once we receive a buffer
// with the correct size.
@@ -477,15 +816,117 @@
}
}
- return LayerBase::doTransaction(flags);
+ // always set active to requested, unless we're asked not to
+ // this is used by Layer, which special cases resizes.
+ if (flags & eDontUpdateGeometryState) {
+ } else {
+ Layer::State& editTemp(currentState());
+ editTemp.active = temp.requested;
+ }
+
+ if (front.active != temp.active) {
+ // invalidate and recompute the visible regions if needed
+ flags |= Layer::eVisibleRegion;
+ }
+
+ if (temp.sequence != front.sequence) {
+ // invalidate and recompute the visible regions if needed
+ flags |= eVisibleRegion;
+ this->contentDirty = true;
+
+ // we may use linear filtering, if the matrix scales us
+ const uint8_t type = temp.transform.getType();
+ mNeedsFiltering = (!temp.transform.preserveRects() ||
+ (type >= Transform::SCALE));
+ }
+
+ // Commit the transaction
+ commitTransaction();
+ return flags;
}
-bool Layer::isFixedSize() const {
- return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
+void Layer::commitTransaction() {
+ mDrawingState = mCurrentState;
}
-bool Layer::isCropped() const {
- return !mCurrentCrop.isEmpty();
+uint32_t Layer::getTransactionFlags(uint32_t flags) {
+ return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+
+uint32_t Layer::setTransactionFlags(uint32_t flags) {
+ return android_atomic_or(flags, &mTransactionFlags);
+}
+
+bool Layer::setPosition(float x, float y) {
+ if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.transform.set(x, y);
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setLayer(uint32_t z) {
+ if (mCurrentState.z == z)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.z = z;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setSize(uint32_t w, uint32_t h) {
+ if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
+ return false;
+ mCurrentState.requested.w = w;
+ mCurrentState.requested.h = h;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setAlpha(uint8_t alpha) {
+ if (mCurrentState.alpha == alpha)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.alpha = alpha;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
+ mCurrentState.sequence++;
+ mCurrentState.transform.set(
+ matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setTransparentRegionHint(const Region& transparent) {
+ mCurrentState.sequence++;
+ mCurrentState.transparentRegion = transparent;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setFlags(uint8_t flags, uint8_t mask) {
+ const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+ if (mCurrentState.flags == newFlags)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.flags = newFlags;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+bool Layer::setCrop(const Rect& crop) {
+ if (mCurrentState.requested.crop == crop)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.requested.crop = crop;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
+bool Layer::setLayerStack(uint32_t layerStack) {
+ if (mCurrentState.layerStack == layerStack)
+ return false;
+ mCurrentState.sequence++;
+ mCurrentState.layerStack = layerStack;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
}
// ----------------------------------------------------------------------------
@@ -528,7 +969,9 @@
}
bool Layer::isVisible() const {
- return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
+ const Layer::State& s(mDrawingState);
+ return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
+ && (mActiveBuffer != NULL);
}
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
@@ -702,44 +1145,6 @@
return outDirtyRegion;
}
-void Layer::dump(String8& result, char* buffer, size_t SIZE) const
-{
- LayerBaseClient::dump(result, buffer, SIZE);
-
- sp<const GraphicBuffer> buf0(mActiveBuffer);
- uint32_t w0=0, h0=0, s0=0, f0=0;
- if (buf0 != 0) {
- w0 = buf0->getWidth();
- h0 = buf0->getHeight();
- s0 = buf0->getStride();
- f0 = buf0->format;
- }
- snprintf(buffer, SIZE,
- " "
- "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
- " queued-frames=%d, mRefreshPending=%d\n",
- mFormat, w0, h0, s0,f0,
- mQueuedFrames, mRefreshPending);
-
- result.append(buffer);
-
- if (mSurfaceFlingerConsumer != 0) {
- mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE);
- }
-}
-
-void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
-{
- LayerBaseClient::dumpStats(result, buffer, SIZE);
- mFrameTracker.dump(result);
-}
-
-void Layer::clearStats()
-{
- LayerBaseClient::clearStats();
- mFrameTracker.clear();
-}
-
uint32_t Layer::getEffectiveUsage(uint32_t usage) const
{
// TODO: should we do something special if mSecure is set?
@@ -766,6 +1171,86 @@
mSurfaceFlingerConsumer->setTransformHint(orientation);
}
+// ----------------------------------------------------------------------------
+// debugging
+// ----------------------------------------------------------------------------
+
+void Layer::dump(String8& result, char* buffer, size_t SIZE) const
+{
+ const Layer::State& s(drawingState());
+
+ snprintf(buffer, SIZE,
+ "+ %s %p (%s)\n",
+ getTypeId(), this, getName().string());
+ result.append(buffer);
+
+ s.transparentRegion.dump(result, "transparentRegion");
+ visibleRegion.dump(result, "visibleRegion");
+ sp<Client> client(mClientRef.promote());
+
+ snprintf(buffer, SIZE,
+ " "
+ "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
+ "isOpaque=%1d, invalidate=%1d, "
+ "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
+ " client=%p\n",
+ s.layerStack, s.z, 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(), contentDirty,
+ s.alpha, s.flags,
+ s.transform[0][0], s.transform[0][1],
+ s.transform[1][0], s.transform[1][1],
+ client.get());
+ result.append(buffer);
+
+ sp<const GraphicBuffer> buf0(mActiveBuffer);
+ uint32_t w0=0, h0=0, s0=0, f0=0;
+ if (buf0 != 0) {
+ w0 = buf0->getWidth();
+ h0 = buf0->getHeight();
+ s0 = buf0->getStride();
+ f0 = buf0->format;
+ }
+ snprintf(buffer, SIZE,
+ " "
+ "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
+ " queued-frames=%d, mRefreshPending=%d\n",
+ mFormat, w0, h0, s0,f0,
+ mQueuedFrames, mRefreshPending);
+
+ result.append(buffer);
+
+ if (mSurfaceFlingerConsumer != 0) {
+ mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE);
+ }
+}
+
+
+void Layer::shortDump(String8& result, char* scratch, size_t size) const {
+ Layer::dump(result, scratch, size);
+}
+
+void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const {
+ mFrameTracker.dump(result);
+}
+
+void Layer::clearStats() {
+ mFrameTracker.clear();
+}
+
+// ---------------------------------------------------------------------------
+
+Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
+ const sp<Layer>& layer)
+ : mFlinger(flinger), mLayer(layer) {
+}
+
+Layer::LayerCleaner::~LayerCleaner() {
+ // destroy client resources
+ mFlinger->onLayerDestroyed(mLayer);
+}
+
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e57fb59..5fb6d8b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -20,118 +20,356 @@
#include <stdint.h>
#include <sys/types.h>
-#include <utils/Timers.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-
-#include <gui/ISurfaceComposerClient.h>
-
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
-#include "SurfaceFlingerConsumer.h"
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Timers.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+
+#include <gui/ISurfaceComposerClient.h>
+
+#include <private/gui/LayerState.h>
+
#include "FrameTracker.h"
-#include "LayerBase.h"
+#include "Client.h"
+#include "SurfaceFlinger.h"
+#include "SurfaceFlingerConsumer.h"
#include "SurfaceTextureLayer.h"
#include "Transform.h"
+#include "DisplayHardware/HWComposer.h"
+
namespace android {
// ---------------------------------------------------------------------------
class Client;
+class DisplayDevice;
+class GraphicBuffer;
+class SurfaceFlinger;
class GLExtensions;
// ---------------------------------------------------------------------------
/*
- * The Layer class is essentially a LayerBase combined with a BufferQueue.
* A new BufferQueue and a new SurfaceFlingerConsumer are created when the
* Layer is first referenced.
*
* This also implements onFrameAvailable(), which notifies SurfaceFlinger
* that new data has arrived.
*/
-class Layer : public LayerBaseClient,
- public SurfaceFlingerConsumer::FrameAvailableListener
-{
+class Layer : public SurfaceFlingerConsumer::FrameAvailableListener {
+ static int32_t sSequence;
+
public:
+ mutable bool contentDirty;
+ // regions below are in window-manager space
+ Region visibleRegion;
+ Region coveredRegion;
+ Region visibleNonTransparentRegion;
+ int32_t sequence;
+
+ enum { // flags for doTransaction()
+ eDontUpdateGeometryState = 0x00000001,
+ eVisibleRegion = 0x00000002,
+ };
+
+ struct Geometry {
+ uint32_t w;
+ uint32_t h;
+ Rect crop;
+ inline bool operator ==(const Geometry& rhs) const {
+ return (w == rhs.w && h == rhs.h && crop == rhs.crop);
+ }
+ inline bool operator !=(const Geometry& rhs) const {
+ return !operator ==(rhs);
+ }
+ };
+
+ struct State {
+ Geometry active;
+ Geometry requested;
+ uint32_t z;
+ uint32_t layerStack;
+ uint8_t alpha;
+ uint8_t flags;
+ uint8_t reserved[2];
+ int32_t sequence; // changes when visible regions can change
+ Transform transform;
+ Region transparentRegion;
+ };
+
+ class LayerMesh {
+ friend class Layer;
+ GLfloat mVertices[4][2];
+ size_t mNumVertices;
+ public:
+ LayerMesh() :
+ mNumVertices(4) {
+ }
+ GLfloat const* getVertices() const {
+ return &mVertices[0][0];
+ }
+ size_t getVertexCount() const {
+ return mNumVertices;
+ }
+ };
+
+ // -----------------------------------------------------------------------
+
Layer(SurfaceFlinger* flinger, const sp<Client>& client);
virtual ~Layer();
- virtual const char* getTypeId() const { return "Layer"; }
-
// the this layer's size and format
status_t setBuffers(uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags=0);
- bool isFixedSize() const;
+ // Creates an ISurface associated with this object. This may only be
+ // called once. to provide your own ISurface, override createSurface().
+ sp<ISurface> getSurface();
- // LayerBase interface
+ // modify current state
+ bool setPosition(float x, float y);
+ bool setLayer(uint32_t z);
+ bool setSize(uint32_t w, uint32_t h);
+ bool setAlpha(uint8_t alpha);
+ bool setMatrix(const layer_state_t::matrix22_t& matrix);
+ bool setTransparentRegionHint(const Region& transparent);
+ bool setFlags(uint8_t flags, uint8_t mask);
+ bool setCrop(const Rect& crop);
+ bool setLayerStack(uint32_t layerStack);
+
+ void commitTransaction();
+
+ uint32_t getTransactionFlags(uint32_t flags);
+ uint32_t setTransactionFlags(uint32_t flags);
+
+ void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
+ Rect computeBounds() const;
+
+ // -----------------------------------------------------------------------
+
+ /*
+ * initStates - called just after construction
+ */
+ virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+
+ virtual const char* getTypeId() const { return "Layer"; }
+
+ virtual void setName(const String8& name);
+ String8 getName() const;
+
virtual void setGeometry(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface& layer);
+
+ /*
+ * called after page-flip
+ */
virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
HWComposer::HWCLayerInterface* layer);
+
+ /*
+ * called before composition.
+ * returns true if the layer has pending updates.
+ */
virtual bool onPreComposition();
+
+ /*
+ * called after composition.
+ */
virtual void onPostComposition();
+ /*
+ * draw - performs some global clipping optimizations
+ * and calls onDraw().
+ * Typically this method is not overridden, instead implement onDraw()
+ * to perform the actual drawing.
+ */
+ virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+ virtual void draw(const sp<const DisplayDevice>& hw);
+
+ /*
+ * onDraw - draws the surface.
+ */
virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+
+ /*
+ * needsLinearFiltering - true if this surface's state requires filtering
+ */
+ virtual bool needsFiltering(const sp<const DisplayDevice>& hw) const;
+
+ /*
+ * doTransaction - process the transaction. This is a good place to figure
+ * out which attributes of the surface have changed.
+ */
virtual uint32_t doTransaction(uint32_t transactionFlags);
+
+ /*
+ * setVisibleRegion - called to set the new visible region. This gives
+ * a chance to update the new visible region or record the fact it changed.
+ */
+ virtual void setVisibleRegion(const Region& visibleRegion);
+
+ /*
+ * setCoveredRegion - called when the covered region changes. The covered
+ * region corresponds to any area of the surface that is covered
+ * (transparently or not) by another surface.
+ */
+ virtual void setCoveredRegion(const Region& coveredRegion);
+
+ /*
+ * setVisibleNonTransparentRegion - called when the visible and
+ * non-transparent region changes.
+ */
+ virtual void setVisibleNonTransparentRegion(const Region&
+ visibleNonTransparentRegion);
+
+ /*
+ * latchBuffer - called each time the screen is redrawn and returns whether
+ * the visible regions need to be recomputed (this is a fairly heavy
+ * operation, so this should be set only if needed). Typically this is used
+ * to figure out if the content or size of a surface has changed.
+ */
virtual Region latchBuffer(bool& recomputeVisibleRegions);
+
+ /*
+ * isOpaque - true if this surface is opaque
+ */
virtual bool isOpaque() const;
+
+ /*
+ * isSecure - true if this surface is secure, that is if it prevents
+ * screenshots or VNC servers.
+ */
virtual bool isSecure() const { return mSecure; }
+
+ /*
+ * isProtected - true if the layer may contain protected content in the
+ * GRALLOC_USAGE_PROTECTED sense.
+ */
virtual bool isProtected() const;
- virtual void onRemoved();
- virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
- virtual void setName(const String8& name);
+
+ /*
+ * isVisible - true if this layer is visible, false otherwise
+ */
virtual bool isVisible() const;
- // LayerBaseClient interface
- virtual wp<IBinder> getSurfaceTextureBinder() const;
+ /*
+ * isFixedSize - true if content has a fixed size
+ */
+ virtual bool isFixedSize() const;
- // only for debugging
- inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
+ /*
+ * called with the state lock when the surface is removed from the
+ * current list
+ */
+ virtual void onRemoved();
+
+
+ virtual wp<IBinder> getSurfaceTextureBinder() const;
// Updates the transform hint in our SurfaceFlingerConsumer to match
// the current orientation of the display device.
virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const;
+ /*
+ * returns the rectangle that crops the content of the layer and scales it
+ * to the layer's size.
+ */
virtual Rect getContentCrop() const;
+
+ /*
+ * returns the transform bits (90 rotation / h-flip / v-flip) of the
+ * layer's content
+ */
virtual uint32_t getContentTransform() const;
-protected:
- virtual void onFirstRef();
+ // -----------------------------------------------------------------------
+
+ void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
+ void setFiltering(bool filtering);
+ bool getFiltering() const;
+
+ // only for debugging
+ inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
+
+ inline const State& drawingState() const { return mDrawingState; }
+ inline const State& currentState() const { return mCurrentState; }
+ inline State& currentState() { return mCurrentState; }
+
+
+ /* always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
virtual void clearStats();
- sp<SurfaceFlingerConsumer> getConsumer() const {
- return mSurfaceFlingerConsumer;
- }
+protected:
+ // constant
+ sp<SurfaceFlinger> mFlinger;
+
+ virtual void onFirstRef();
+
+ /*
+ * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer)
+ * is called.
+ */
+ class LayerCleaner {
+ sp<SurfaceFlinger> mFlinger;
+ wp<Layer> mLayer;
+ protected:
+ ~LayerCleaner();
+ public:
+ LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer);
+ };
+
private:
// Creates an instance of ISurface for this Layer.
virtual sp<ISurface> createSurface();
+ // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
+ virtual void onFrameAvailable();
+
+
uint32_t getEffectiveUsage(uint32_t usage) const;
+ Rect computeCrop(const sp<const DisplayDevice>& hw) const;
bool isCropped() const;
static bool getOpacityForFormat(uint32_t format);
- // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
- virtual void onFrameAvailable();
+ // drawing
+ void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
+ GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;
+ void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
+
// -----------------------------------------------------------------------
// constants
sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
GLuint mTextureName;
+ bool mPremultipliedAlpha;
+ String8 mName;
+ mutable bool mDebug;
+ PixelFormat mFormat;
+ const GLExtensions& mGLExtensions;
+ bool mOpaqueLayer;
+
+ // these are protected by an external lock
+ State mCurrentState;
+ State mDrawingState;
+ volatile int32_t mTransactionFlags;
// thread-safe
volatile int32_t mQueuedFrames;
@@ -145,15 +383,20 @@
bool mCurrentOpacity;
bool mRefreshPending;
bool mFrameLatencyNeeded;
-
- // constants
- PixelFormat mFormat;
- const GLExtensions& mGLExtensions;
- bool mOpaqueLayer;
+ // Whether filtering is forced on or not
+ bool mFiltering;
+ // Whether filtering is needed b/c of the drawingstate
+ bool mNeedsFiltering;
// page-flip thread (currently main thread)
- bool mSecure; // no screenshots
+ bool mSecure; // no screenshots
bool mProtectedByApp; // application requires protected path to external sink
+
+ // protected by mLock
+ mutable Mutex mLock;
+ // Set to true if an ISurface has been associated with this object.
+ mutable bool mHasSurface;
+ const wp<Client> mClientRef;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
deleted file mode 100644
index db2b20e..0000000
--- a/services/surfaceflinger/LayerBase.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <math.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include <hardware/hardware.h>
-
-#include "clz.h"
-#include "Client.h"
-#include "LayerBase.h"
-#include "Layer.h"
-#include "SurfaceFlinger.h"
-#include "DisplayDevice.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-int32_t LayerBase::sSequence = 1;
-
-LayerBase::LayerBase(SurfaceFlinger* flinger)
- : contentDirty(false),
- sequence(uint32_t(android_atomic_inc(&sSequence))),
- mFlinger(flinger), mFiltering(false),
- mNeedsFiltering(false),
- mTransactionFlags(0),
- mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
-{
-}
-
-LayerBase::~LayerBase()
-{
-}
-
-void LayerBase::setName(const String8& name) {
- mName = name;
-}
-
-String8 LayerBase::getName() const {
- return mName;
-}
-
-void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
- uint32_t layerFlags = 0;
- if (flags & ISurfaceComposerClient::eHidden)
- layerFlags = layer_state_t::eLayerHidden;
-
- if (flags & ISurfaceComposerClient::eNonPremultiplied)
- mPremultipliedAlpha = false;
-
- mCurrentState.active.w = w;
- mCurrentState.active.h = h;
- mCurrentState.active.crop.makeInvalid();
- mCurrentState.z = 0;
- mCurrentState.alpha = 0xFF;
- mCurrentState.layerStack = 0;
- mCurrentState.flags = layerFlags;
- mCurrentState.sequence = 0;
- mCurrentState.transform.set(0, 0);
- mCurrentState.requested = mCurrentState.active;
-
- // drawing state & current state are identical
- mDrawingState = mCurrentState;
-}
-
-bool LayerBase::needsFiltering(const sp<const DisplayDevice>& hw) const {
- return mNeedsFiltering || hw->needsFiltering();
-}
-
-void LayerBase::commitTransaction() {
- mDrawingState = mCurrentState;
-}
-void LayerBase::forceVisibilityTransaction() {
- // this can be called without SurfaceFlinger.mStateLock, but if we
- // can atomically increment the sequence number, it doesn't matter.
- android_atomic_inc(&mCurrentState.sequence);
- requestTransaction();
-}
-bool LayerBase::requestTransaction() {
- int32_t old = setTransactionFlags(eTransactionNeeded);
- return ((old & eTransactionNeeded) == 0);
-}
-uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
- return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
- return android_atomic_or(flags, &mTransactionFlags);
-}
-
-bool LayerBase::setPosition(float x, float y) {
- if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
- return false;
- mCurrentState.sequence++;
- mCurrentState.transform.set(x, y);
- requestTransaction();
- return true;
-}
-bool LayerBase::setLayer(uint32_t z) {
- if (mCurrentState.z == z)
- return false;
- mCurrentState.sequence++;
- mCurrentState.z = z;
- requestTransaction();
- return true;
-}
-bool LayerBase::setSize(uint32_t w, uint32_t h) {
- if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
- return false;
- mCurrentState.requested.w = w;
- mCurrentState.requested.h = h;
- requestTransaction();
- return true;
-}
-bool LayerBase::setAlpha(uint8_t alpha) {
- if (mCurrentState.alpha == alpha)
- return false;
- mCurrentState.sequence++;
- mCurrentState.alpha = alpha;
- requestTransaction();
- return true;
-}
-bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
- mCurrentState.sequence++;
- mCurrentState.transform.set(
- matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
- requestTransaction();
- return true;
-}
-bool LayerBase::setTransparentRegionHint(const Region& transparent) {
- mCurrentState.sequence++;
- mCurrentState.transparentRegion = transparent;
- requestTransaction();
- return true;
-}
-bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
- const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
- if (mCurrentState.flags == newFlags)
- return false;
- mCurrentState.sequence++;
- mCurrentState.flags = newFlags;
- requestTransaction();
- return true;
-}
-bool LayerBase::setCrop(const Rect& crop) {
- if (mCurrentState.requested.crop == crop)
- return false;
- mCurrentState.sequence++;
- mCurrentState.requested.crop = crop;
- requestTransaction();
- return true;
-}
-
-bool LayerBase::setLayerStack(uint32_t layerStack) {
- if (mCurrentState.layerStack == layerStack)
- return false;
- mCurrentState.sequence++;
- mCurrentState.layerStack = layerStack;
- requestTransaction();
- return true;
-}
-
-void LayerBase::setVisibleRegion(const Region& visibleRegion) {
- // always called from main thread
- this->visibleRegion = visibleRegion;
-}
-
-void LayerBase::setCoveredRegion(const Region& coveredRegion) {
- // always called from main thread
- this->coveredRegion = coveredRegion;
-}
-
-void LayerBase::setVisibleNonTransparentRegion(const Region&
- setVisibleNonTransparentRegion) {
- // always called from main thread
- this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
-}
-
-uint32_t LayerBase::doTransaction(uint32_t flags)
-{
- const Layer::State& front(drawingState());
- const Layer::State& temp(currentState());
-
- // always set active to requested, unless we're asked not to
- // this is used by Layer, which special cases resizes.
- if (flags & eDontUpdateGeometryState) {
- } else {
- Layer::State& editTemp(currentState());
- editTemp.active = temp.requested;
- }
-
- if (front.active != temp.active) {
- // invalidate and recompute the visible regions if needed
- flags |= Layer::eVisibleRegion;
- }
-
- if (temp.sequence != front.sequence) {
- // invalidate and recompute the visible regions if needed
- flags |= eVisibleRegion;
- this->contentDirty = true;
-
- // we may use linear filtering, if the matrix scales us
- const uint8_t type = temp.transform.getType();
- mNeedsFiltering = (!temp.transform.preserveRects() ||
- (type >= Transform::SCALE));
- }
-
- // Commit the transaction
- commitTransaction();
- return flags;
-}
-
-void LayerBase::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
-{
- const Layer::State& s(drawingState());
- const Transform tr(hw->getTransform() * s.transform);
- const uint32_t hw_h = hw->getHeight();
- Rect win(s.active.w, s.active.h);
- if (!s.active.crop.isEmpty()) {
- win.intersect(s.active.crop, &win);
- }
- if (mesh) {
- tr.transform(mesh->mVertices[0], win.left, win.top);
- tr.transform(mesh->mVertices[1], win.left, win.bottom);
- tr.transform(mesh->mVertices[2], win.right, win.bottom);
- tr.transform(mesh->mVertices[3], win.right, win.top);
- for (size_t i=0 ; i<4 ; i++) {
- mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
- }
- }
-}
-
-Rect LayerBase::computeBounds() const {
- const Layer::State& s(drawingState());
- Rect win(s.active.w, s.active.h);
- if (!s.active.crop.isEmpty()) {
- win.intersect(s.active.crop, &win);
- }
- return win;
-}
-
-Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) {
- Region result;
- return result;
-}
-
-
-Rect LayerBase::getContentCrop() const {
- // regular layers just use their active area as the content crop
- const State& s(drawingState());
- return Rect(s.active.w, s.active.h);
-}
-
-uint32_t LayerBase::getContentTransform() const {
- // regular layers don't have a content transform
- return 0;
-}
-
-Rect LayerBase::computeCrop(const sp<const DisplayDevice>& hw) const {
- /*
- * The way we compute the crop (aka. texture coordinates when we have a
- * Layer) produces a different output from the GL code in
- * drawWithOpenGL() due to HWC being limited to integers. The difference
- * can be large if getContentTransform() contains a large scale factor.
- * See comments in drawWithOpenGL() for more details.
- */
-
- // the content crop is the area of the content that gets scaled to the
- // layer's size.
- Rect crop(getContentCrop());
-
- // the active.crop is the area of the window that gets cropped, but not
- // scaled in any ways.
- const State& s(drawingState());
-
- // apply the projection's clipping to the window crop in
- // layerstack space, and convert-back to layer space.
- // if there are no window scaling (or content scaling) involved,
- // this operation will map to full pixels in the buffer.
- // NOTE: should we revert to GL composition if a scaling is involved
- // since it cannot be represented in the HWC API?
- Rect activeCrop(s.transform.transform(s.active.crop));
- activeCrop.intersect(hw->getViewport(), &activeCrop);
- activeCrop = s.transform.inverse().transform(activeCrop);
-
- // paranoia: make sure the window-crop is constrained in the
- // window's bounds
- activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
-
- if (!activeCrop.isEmpty()) {
- // Transform the window crop to match the buffer coordinate system,
- // which means using the inverse of the current transform set on the
- // SurfaceFlingerConsumer.
- uint32_t invTransform = getContentTransform();
- int winWidth = s.active.w;
- int winHeight = s.active.h;
- if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
- invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
- NATIVE_WINDOW_TRANSFORM_FLIP_H;
- winWidth = s.active.h;
- winHeight = s.active.w;
- }
- const Rect winCrop = activeCrop.transform(
- invTransform, s.active.w, s.active.h);
-
- // the code below essentially performs a scaled intersection
- // of crop and winCrop
- float xScale = float(crop.width()) / float(winWidth);
- float yScale = float(crop.height()) / float(winHeight);
-
- int insetL = int(ceilf( winCrop.left * xScale));
- int insetT = int(ceilf( winCrop.top * yScale));
- int insetR = int(ceilf((winWidth - winCrop.right ) * xScale));
- int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
-
- crop.left += insetL;
- crop.top += insetT;
- crop.right -= insetR;
- crop.bottom -= insetB;
- }
- return crop;
-}
-
-void LayerBase::setGeometry(
- const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer)
-{
- layer.setDefaultState();
-
- // this gives us only the "orientation" component of the transform
- const State& s(drawingState());
- const uint32_t finalTransform = s.transform.getOrientation();
- // we can only handle simple transformation
- if (finalTransform & Transform::ROT_INVALID) {
- layer.setTransform(0);
- } else {
- layer.setTransform(finalTransform);
- }
-
- if (!isOpaque() || s.alpha != 0xFF) {
- layer.setBlending(mPremultipliedAlpha ?
- HWC_BLENDING_PREMULT :
- HWC_BLENDING_COVERAGE);
- }
-
-
- // apply the layer's transform, followed by the display's global transform
- // here we're guaranteed that the layer's transform preserves rects
-
- Rect frame(s.transform.transform(computeBounds()));
- frame.intersect(hw->getViewport(), &frame);
- const Transform& tr(hw->getTransform());
- layer.setFrame(tr.transform(frame));
- layer.setCrop(computeCrop(hw));
-}
-
-void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer) {
- // we have to set the visible region on every frame because
- // we currently free it during onLayerDisplayed(), which is called
- // after HWComposer::commit() -- every frame.
- // Apply this display's projection's viewport to the visible region
- // before giving it to the HWC HAL.
- const Transform& tr = hw->getTransform();
- Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
- layer.setVisibleRegionScreen(visible);
-}
-
-void LayerBase::setAcquireFence(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer) {
- layer.setAcquireFenceFd(-1);
-}
-
-void LayerBase::onLayerDisplayed(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface* layer) {
- if (layer) {
- layer->onDisplayed();
- }
-}
-
-void LayerBase::setFiltering(bool filtering)
-{
- mFiltering = filtering;
-}
-
-bool LayerBase::getFiltering() const
-{
- return mFiltering;
-}
-
-bool LayerBase::isVisible() const {
- const Layer::State& s(mDrawingState);
- return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
-}
-
-void LayerBase::draw(const sp<const DisplayDevice>& hw, const Region& clip) const
-{
- onDraw(hw, clip);
-}
-
-void LayerBase::draw(const sp<const DisplayDevice>& hw)
-{
- onDraw( hw, Region(hw->bounds()) );
-}
-
-void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
- GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
-{
- const uint32_t fbHeight = hw->getHeight();
- glColor4f(red,green,blue,alpha);
-
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- LayerMesh mesh;
- computeGeometry(hw, &mesh);
-
- glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
- glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
-}
-
-void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
-{
- clearWithOpenGL(hw, clip, 0,0,0,0);
-}
-
-void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
-{
- const uint32_t fbHeight = hw->getHeight();
- const State& s(drawingState());
-
- GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
- if (CC_UNLIKELY(s.alpha < 0xFF)) {
- const GLfloat alpha = s.alpha * (1.0f/255.0f);
- if (mPremultipliedAlpha) {
- glColor4f(alpha, alpha, alpha, alpha);
- } else {
- glColor4f(1, 1, 1, alpha);
- }
- glEnable(GL_BLEND);
- glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- } else {
- glColor4f(1, 1, 1, 1);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- if (!isOpaque()) {
- glEnable(GL_BLEND);
- glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glDisable(GL_BLEND);
- }
- }
-
- LayerMesh mesh;
- computeGeometry(hw, &mesh);
-
- // TODO: we probably want to generate the texture coords with the mesh
- // here we assume that we only have 4 vertices
-
- struct TexCoords {
- GLfloat u;
- GLfloat v;
- };
-
-
- /*
- * NOTE: the way we compute the texture coordinates here produces
- * different results than when we take the HWC path -- in the later case
- * the "source crop" is rounded to texel boundaries.
- * This can produce significantly different results when the texture
- * is scaled by a large amount.
- *
- * The GL code below is more logical (imho), and the difference with
- * HWC is due to a limitation of the HWC API to integers -- a question
- * is suspend is wether we should ignore this problem or revert to
- * GL composition when a buffer scaling is applied (maybe with some
- * minimal value)? Or, we could make GL behave like HWC -- but this feel
- * like more of a hack.
- */
- const Rect win(computeBounds());
-
- GLfloat left = GLfloat(win.left) / GLfloat(s.active.w);
- GLfloat top = GLfloat(win.top) / GLfloat(s.active.h);
- GLfloat right = GLfloat(win.right) / GLfloat(s.active.w);
- GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
-
- TexCoords texCoords[4];
- texCoords[0].u = left;
- texCoords[0].v = top;
- texCoords[1].u = left;
- texCoords[1].v = bottom;
- texCoords[2].u = right;
- texCoords[2].v = bottom;
- texCoords[3].u = right;
- texCoords[3].v = top;
- for (int i = 0; i < 4; i++) {
- texCoords[i].v = 1.0f - texCoords[i].v;
- }
-
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
- glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glDisable(GL_BLEND);
-}
-
-void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
-{
- const Layer::State& s(drawingState());
-
- snprintf(buffer, SIZE,
- "+ %s %p (%s)\n",
- getTypeId(), this, getName().string());
- result.append(buffer);
-
- s.transparentRegion.dump(result, "transparentRegion");
- visibleRegion.dump(result, "visibleRegion");
-
- snprintf(buffer, SIZE,
- " "
- "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.layerStack, s.z, 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,
- s.alpha, s.flags,
- s.transform[0][0], s.transform[0][1],
- s.transform[1][0], s.transform[1][1]);
- result.append(buffer);
-}
-
-void LayerBase::shortDump(String8& result, char* scratch, size_t size) const {
- LayerBase::dump(result, scratch, size);
-}
-
-void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const {
-}
-
-void LayerBase::clearStats() {
-}
-
-sp<LayerBaseClient> LayerBase::getLayerBaseClient() const {
- return 0;
-}
-
-sp<Layer> LayerBase::getLayer() const {
- return 0;
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger,
- const sp<Client>& client)
- : LayerBase(flinger),
- mHasSurface(false),
- mClientRef(client)
-{
-}
-
-LayerBaseClient::~LayerBaseClient()
-{
- sp<Client> c(mClientRef.promote());
- if (c != 0) {
- c->detachLayer(this);
- }
-}
-
-sp<ISurface> LayerBaseClient::createSurface()
-{
- class BSurface : public BnSurface, public LayerCleaner {
- virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; }
- public:
- BSurface(const sp<SurfaceFlinger>& flinger,
- const sp<LayerBaseClient>& layer)
- : LayerCleaner(flinger, layer) { }
- };
- sp<ISurface> sur(new BSurface(mFlinger, this));
- return sur;
-}
-
-sp<ISurface> LayerBaseClient::getSurface()
-{
- sp<ISurface> s;
- Mutex::Autolock _l(mLock);
-
- LOG_ALWAYS_FATAL_IF(mHasSurface,
- "LayerBaseClient::getSurface() has already been called");
-
- mHasSurface = true;
- s = createSurface();
- mClientSurfaceBinder = s->asBinder();
- return s;
-}
-
-wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
- return mClientSurfaceBinder;
-}
-
-wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
- return 0;
-}
-
-void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
-{
- LayerBase::dump(result, buffer, SIZE);
- sp<Client> client(mClientRef.promote());
- snprintf(buffer, SIZE, " client=%p\n", client.get());
- result.append(buffer);
-}
-
-
-void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
-{
- LayerBaseClient::dump(result, scratch, size);
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
- const sp<LayerBaseClient>& layer)
- : mFlinger(flinger), mLayer(layer) {
-}
-
-LayerBaseClient::LayerCleaner::~LayerCleaner() {
- // destroy client resources
- mFlinger->onLayerDestroyed(mLayer);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
deleted file mode 100644
index ecae2d9..0000000
--- a/services/surfaceflinger/LayerBase.h
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LAYER_BASE_H
-#define ANDROID_LAYER_BASE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#include <ui/Region.h>
-
-#include <gui/ISurfaceComposerClient.h>
-
-#include <private/gui/LayerState.h>
-
-#include "Transform.h"
-#include "DisplayHardware/HWComposer.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Client;
-class DisplayDevice;
-class GraphicBuffer;
-class Layer;
-class LayerBaseClient;
-class SurfaceFlinger;
-
-// ---------------------------------------------------------------------------
-
-/*
- * Layers are rectangular graphic entities, internal to SurfaceFlinger.
- * They have properties including width, height, Z-depth, and 2D
- * transformations (chiefly translation and 90-degree rotations).
- *
- * Layers are organized into "layer stacks". Each layer is a member of
- * exactly one layer stack, identified by an integer in Layer::State. A
- * given layer stack may appear on more than one display.
- *
- * Notable subclasses (below LayerBaseClient) include Layer, LayerDim, and
- * LayerScreenshot.
- */
-class LayerBase : virtual public RefBase
-{
- static int32_t sSequence;
-
-public:
- LayerBase(SurfaceFlinger* flinger);
-
- mutable bool contentDirty;
- // regions below are in window-manager space
- Region visibleRegion;
- Region coveredRegion;
- Region visibleNonTransparentRegion;
- int32_t sequence;
-
- struct Geometry {
- uint32_t w;
- uint32_t h;
- Rect crop;
- inline bool operator == (const Geometry& rhs) const {
- return (w==rhs.w && h==rhs.h && crop==rhs.crop);
- }
- inline bool operator != (const Geometry& rhs) const {
- return !operator == (rhs);
- }
- };
-
- struct State {
- Geometry active;
- Geometry requested;
- uint32_t z;
- uint32_t layerStack;
- uint8_t alpha;
- uint8_t flags;
- uint8_t reserved[2];
- int32_t sequence; // changes when visible regions can change
- Transform transform;
- Region transparentRegion;
- };
-
- class LayerMesh {
- friend class LayerBase;
- GLfloat mVertices[4][2];
- size_t mNumVertices;
- public:
- LayerMesh() : mNumVertices(4) { }
- GLfloat const* getVertices() const {
- return &mVertices[0][0];
- }
- size_t getVertexCount() const {
- return mNumVertices;
- }
- };
-
- virtual void setName(const String8& name);
- String8 getName() const;
-
- // modify current state
- bool setPosition(float x, float y);
- bool setLayer(uint32_t z);
- bool setSize(uint32_t w, uint32_t h);
- bool setAlpha(uint8_t alpha);
- bool setMatrix(const layer_state_t::matrix22_t& matrix);
- bool setTransparentRegionHint(const Region& transparent);
- bool setFlags(uint8_t flags, uint8_t mask);
- bool setCrop(const Rect& crop);
- bool setLayerStack(uint32_t layerStack);
-
- void commitTransaction();
- bool requestTransaction();
- void forceVisibilityTransaction();
-
- uint32_t getTransactionFlags(uint32_t flags);
- uint32_t setTransactionFlags(uint32_t flags);
-
- void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
- Rect computeBounds() const;
-
-
- virtual sp<LayerBaseClient> getLayerBaseClient() const;
- virtual sp<Layer> getLayer() const;
-
- virtual const char* getTypeId() const { return "LayerBase"; }
-
- virtual void setGeometry(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer);
- virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer);
- virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer);
-
- /**
- * draw - performs some global clipping optimizations
- * and calls onDraw().
- * Typically this method is not overridden, instead implement onDraw()
- * to perform the actual drawing.
- */
- virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
- virtual void draw(const sp<const DisplayDevice>& hw);
-
- /**
- * onDraw - draws the surface.
- */
- virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const = 0;
-
- /**
- * initStates - called just after construction
- */
- virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
-
- /**
- * doTransaction - process the transaction. This is a good place to figure
- * out which attributes of the surface have changed.
- */
- virtual uint32_t doTransaction(uint32_t transactionFlags);
-
- /**
- * setVisibleRegion - called to set the new visible region. This gives
- * a chance to update the new visible region or record the fact it changed.
- */
- virtual void setVisibleRegion(const Region& visibleRegion);
-
- /**
- * setCoveredRegion - called when the covered region changes. The covered
- * region corresponds to any area of the surface that is covered
- * (transparently or not) by another surface.
- */
- virtual void setCoveredRegion(const Region& coveredRegion);
-
- /**
- * setVisibleNonTransparentRegion - called when the visible and
- * non-transparent region changes.
- */
- virtual void setVisibleNonTransparentRegion(const Region&
- visibleNonTransparentRegion);
-
- /**
- * latchBuffer - called each time the screen is redrawn and returns whether
- * the visible regions need to be recomputed (this is a fairly heavy
- * operation, so this should be set only if needed). Typically this is used
- * to figure out if the content or size of a surface has changed.
- */
- virtual Region latchBuffer(bool& recomputeVisibleRegions);
-
- /**
- * isOpaque - true if this surface is opaque
- */
- virtual bool isOpaque() const { return true; }
-
- /**
- * needsDithering - true if this surface needs dithering
- */
- virtual bool needsDithering() const { return false; }
-
- /**
- * needsLinearFiltering - true if this surface's state requires filtering
- */
- virtual bool needsFiltering(const sp<const DisplayDevice>& hw) const;
-
- /**
- * isSecure - true if this surface is secure, that is if it prevents
- * screenshots or VNC servers.
- */
- virtual bool isSecure() const { return false; }
-
- /**
- * isProtected - true if the layer may contain protected content in the
- * GRALLOC_USAGE_PROTECTED sense.
- */
- virtual bool isProtected() const { return false; }
-
- /*
- * isVisible - true if this layer is visibile, false otherwise
- */
- virtual bool isVisible() const;
-
- /** called with the state lock when the surface is removed from the
- * current list */
- virtual void onRemoved() { }
-
- /** called after page-flip
- */
- virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface* layer);
-
- /** called before composition.
- * returns true if the layer has pending updates.
- */
- virtual bool onPreComposition() { return false; }
-
- /** called before composition.
- */
- virtual void onPostComposition() { }
-
- /**
- * Updates the GLConsumer's transform hint, for layers that have
- * a GLConsumer.
- */
- virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { }
-
- /**
- * returns the rectangle that crops the content of the layer and scales it
- * to the layer's size.
- */
- virtual Rect getContentCrop() const;
-
- /*
- * returns the transform bits (90 rotation / h-flip / v-flip) of the
- * layer's content
- */
- virtual uint32_t getContentTransform() const;
-
- /** always call base class first */
- virtual void dump(String8& result, char* scratch, size_t size) const;
- virtual void shortDump(String8& result, char* scratch, size_t size) const;
- virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
- virtual void clearStats();
-
-
- enum { // flags for doTransaction()
- eDontUpdateGeometryState = 0x00000001,
- eVisibleRegion = 0x00000002,
- };
-
-
- inline const State& drawingState() const { return mDrawingState; }
- inline const State& currentState() const { return mCurrentState; }
- inline State& currentState() { return mCurrentState; }
-
- void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
-
- void setFiltering(bool filtering);
- bool getFiltering() const;
-
-private:
- Rect computeCrop(const sp<const DisplayDevice>& hw) const;
-
-protected:
- void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
- GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;
- void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
-
- sp<SurfaceFlinger> mFlinger;
-
-private:
- // accessed only in the main thread
- // Whether filtering is forced on or not
- bool mFiltering;
-
- // Whether filtering is needed b/c of the drawingstate
- bool mNeedsFiltering;
-
-protected:
- // these are protected by an external lock
- State mCurrentState;
- State mDrawingState;
- volatile int32_t mTransactionFlags;
-
- // don't change, don't need a lock
- bool mPremultipliedAlpha;
- String8 mName;
- mutable bool mDebug;
-
-
-public:
- // called from class SurfaceFlinger
- virtual ~LayerBase();
-
-private:
- LayerBase(const LayerBase& rhs);
-};
-
-
-// ---------------------------------------------------------------------------
-
-/*
- * This adds some additional fields and methods to support some Binder IPC
- * interactions. In particular, the LayerBaseClient's lifetime can be
- * managed by references to an ISurface object in another process.
- */
-class LayerBaseClient : public LayerBase
-{
-public:
- LayerBaseClient(SurfaceFlinger* flinger, const sp<Client>& client);
-
- virtual ~LayerBaseClient();
-
- // Creates an ISurface associated with this object. This may only be
- // called once (see also getSurfaceBinder()).
- sp<ISurface> getSurface();
-
- // Returns the Binder object for the ISurface associated with
- // this object.
- wp<IBinder> getSurfaceBinder() const;
-
- virtual wp<IBinder> getSurfaceTextureBinder() const;
-
- virtual sp<LayerBaseClient> getLayerBaseClient() const {
- return const_cast<LayerBaseClient*>(this); }
-
- virtual const char* getTypeId() const { return "LayerBaseClient"; }
-
-protected:
- virtual void dump(String8& result, char* scratch, size_t size) const;
- virtual void shortDump(String8& result, char* scratch, size_t size) const;
-
- /*
- * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer)
- * is called.
- */
- class LayerCleaner {
- sp<SurfaceFlinger> mFlinger;
- wp<LayerBaseClient> mLayer;
- protected:
- ~LayerCleaner();
- public:
- LayerCleaner(const sp<SurfaceFlinger>& flinger,
- const sp<LayerBaseClient>& layer);
- };
-
-private:
- virtual sp<ISurface> createSurface();
-
- mutable Mutex mLock;
-
- // Set to true if an ISurface has been associated with this object.
- mutable bool mHasSurface;
-
- // The ISurface's Binder object, set by getSurface().
- wp<IBinder> mClientSurfaceBinder;
-
- const wp<Client> mClientRef;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BASE_H
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 25caa0a..23decff 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -34,12 +34,10 @@
// ---------------------------------------------------------------------------
LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client)
- : LayerBaseClient(flinger, client)
-{
+ : Layer(flinger, client) {
}
-LayerDim::~LayerDim()
-{
+LayerDim::~LayerDim() {
}
void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
@@ -71,6 +69,25 @@
}
}
+sp<ISurface> LayerDim::createSurface()
+{
+ class BSurface : public BnSurface, public LayerCleaner {
+ virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; }
+ public:
+ BSurface(const sp<SurfaceFlinger>& flinger,
+ const sp<Layer>& layer)
+ : LayerCleaner(flinger, layer) { }
+ };
+ sp<ISurface> sur(new BSurface(mFlinger, this));
+ return sur;
+}
+
+bool LayerDim::isVisible() const {
+ const Layer::State& s(drawingState());
+ return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
+}
+
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index 06f312d..e1ea9bd 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -23,13 +23,13 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include "LayerBase.h"
+#include "Layer.h"
// ---------------------------------------------------------------------------
namespace android {
-class LayerDim : public LayerBaseClient
+class LayerDim : public Layer
{
public:
LayerDim(SurfaceFlinger* flinger, const sp<Client>& client);
@@ -41,6 +41,10 @@
virtual bool isProtectedByApp() const { return false; }
virtual bool isProtectedByDRM() const { return false; }
virtual const char* getTypeId() const { return "LayerDim"; }
+
+ virtual bool isFixedSize() const { return true; }
+ virtual bool isVisible() const;
+ virtual sp<ISurface> createSurface();
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
deleted file mode 100644
index 3470d67..0000000
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "LayerScreenshot.h"
-#include "SurfaceFlinger.h"
-#include "DisplayDevice.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
- const sp<Client>& client)
- : Layer(flinger, client)
-{
-}
-
-void LayerScreenshot::onFirstRef()
-{
- Layer::onFirstRef();
-
- // FIXME: we currently hardcode the default display
- // it's unclear what should we do instead.
- sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
- mFlinger->captureScreenImplLocked(hw, getConsumer()->getBufferQueue(),
- 0, 0, 0, 0x7FFFFFFF);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
deleted file mode 100644
index a2ae03f..0000000
--- a/services/surfaceflinger/LayerScreenshot.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LAYER_SCREENSHOT_H
-#define ANDROID_LAYER_SCREENSHOT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "Layer.h"
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class LayerScreenshot : public Layer
-{
-public:
- LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
-protected:
- virtual void onFirstRef();
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_SCREENSHOT_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a0d2827..5939dc8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -62,7 +62,6 @@
#include "GLExtensions.h"
#include "Layer.h"
#include "LayerDim.h"
-#include "LayerScreenshot.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/FramebufferSurface.h"
@@ -581,17 +580,14 @@
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
- sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
- if (lbc != NULL) {
- // If this is an instance of Layer (as opposed to, say, LayerDim),
- // we will get the consumer interface of SurfaceFlingerConsumer's
- // BufferQueue. If it's the same Binder object as the graphic
- // buffer producer interface, return success.
- wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
- if (lbcBinder == surfaceTextureBinder) {
- return true;
- }
+ const sp<Layer>& layer(currentLayers[i]);
+ // If this is an instance of Layer (as opposed to, say, LayerDim),
+ // we will get the consumer interface of SurfaceFlingerConsumer's
+ // BufferQueue. If it's the same Binder object as the graphic
+ // buffer producer interface, return success.
+ wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder();
+ if (lbcBinder == surfaceTextureBinder) {
+ return true;
}
}
@@ -604,13 +600,10 @@
// should not cause any harm.
size_t purgatorySize = mLayerPurgatory.size();
for (size_t i=0 ; i<purgatorySize ; i++) {
- const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
- sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
- if (lbc != NULL) {
- wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
- if (lbcBinder == surfaceTextureBinder) {
- return true;
- }
+ const sp<Layer>& layer(mLayerPurgatory.itemAt(i));
+ wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder();
+ if (lbcBinder == surfaceTextureBinder) {
+ return true;
}
}
@@ -915,7 +908,7 @@
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
Region opaqueRegion;
Region dirtyRegion;
- Vector< sp<LayerBase> > layersSortedByZ;
+ Vector< sp<Layer> > layersSortedByZ;
const sp<DisplayDevice>& hw(mDisplays[dpy]);
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
@@ -925,7 +918,7 @@
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
const Layer::State& s(layer->drawingState());
if (s.layerStack == hw->getLayerStack()) {
Region drawRegion(tr.transform(
@@ -955,14 +948,14 @@
sp<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();
if (id >= 0) {
- const Vector< sp<LayerBase> >& currentLayers(
+ const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
if (hwc.createWorkList(id, count) == NO_ERROR) {
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]);
+ const sp<Layer>& layer(currentLayers[i]);
layer->setGeometry(hw, *cur);
if (mDebugDisableHWC || mDebugRegion) {
cur->setSkip(true);
@@ -978,7 +971,7 @@
sp<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();
if (id >= 0) {
- const Vector< sp<LayerBase> >& currentLayers(
+ const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
HWComposer::LayerListIterator cur = hwc.begin(id);
@@ -988,7 +981,7 @@
* update the per-frame h/w composer data for each layer
* and build the transparent region of the FB
*/
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
layer->setPerFrameData(hw, *cur);
}
}
@@ -1042,7 +1035,7 @@
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<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
hw->onSwapBuffersCompleted(hwc);
const size_t count = currentLayers.size();
int32_t id = hw->getHwcDisplayId();
@@ -1098,7 +1091,7 @@
if (transactionFlags & eTraversalNeeded) {
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
@@ -1245,8 +1238,8 @@
// NOTE: we rely on the fact that layers are sorted by
// layerStack first (so we don't have to traverse the list
// of displays for every layer).
- const sp<LayerBase>& layerBase(currentLayers[i]);
- uint32_t layerStack = layerBase->drawingState().layerStack;
+ const sp<Layer>& layer(currentLayers[i]);
+ uint32_t layerStack = layer->drawingState().layerStack;
if (i==0 || currentlayerStack != layerStack) {
currentlayerStack = layerStack;
// figure out if this layerstack is mirrored
@@ -1268,7 +1261,7 @@
if (disp != NULL) {
// presumably this means this layer is using a layerStack
// that is not visible on any display
- layerBase->updateTransformHint(disp);
+ layer->updateTransformHint(disp);
}
}
}
@@ -1291,7 +1284,7 @@
mVisibleRegionsDirty = true;
const size_t count = previousLayers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(previousLayers[i]);
+ const sp<Layer>& layer(previousLayers[i]);
if (currentLayers.indexOf(layer) < 0) {
// this layer is not visible anymore
// TODO: we could traverse the tree from front to back and
@@ -1342,7 +1335,7 @@
size_t i = currentLayers.size();
while (i--) {
- const sp<LayerBase>& layer = currentLayers[i];
+ const sp<Layer>& layer = currentLayers[i];
// start with the whole surface at its current location
const Layer::State& s(layer->drawingState());
@@ -1485,7 +1478,7 @@
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]);
+ const sp<Layer>& layer(currentLayers[i]);
const Region dirty(layer->latchBuffer(visibleRegions));
const Layer::State& s(layer->drawingState());
invalidateLayerStack(s.layerStack, dirty);
@@ -1607,13 +1600,13 @@
* and then, render the layers targeted at the framebuffer
*/
- const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
+ const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
const size_t count = layers.size();
const Transform& tr = hw->getTransform();
if (cur != end) {
// we're using h/w composer
for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
- const sp<LayerBase>& layer(layers[i]);
+ const sp<Layer>& layer(layers[i]);
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
switch (cur->getCompositionType()) {
@@ -1645,7 +1638,7 @@
} else {
// we're not using h/w composer
for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer(layers[i]);
+ const sp<Layer>& layer(layers[i]);
const Region clip(dirty.intersect(
tr.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
@@ -1684,7 +1677,7 @@
void SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<IBinder>& handle,
- const sp<LayerBaseClient>& lbc)
+ const sp<Layer>& lbc)
{
// attach this layer to the client
client->attachLayer(handle, lbc);
@@ -1694,7 +1687,7 @@
mCurrentState.layersSortedByZ.add(lbc);
}
-status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer)
{
Mutex::Autolock _l(mStateLock);
status_t err = purgatorizeLayer_l(layer);
@@ -1703,9 +1696,9 @@
return err;
}
-status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
+status_t SurfaceFlinger::removeLayer_l(const sp<Layer>& layer)
{
- ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
+ ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersRemoved = true;
return NO_ERROR;
@@ -1713,16 +1706,16 @@
return status_t(index);
}
-status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
+status_t SurfaceFlinger::purgatorizeLayer_l(const sp<Layer>& layer)
{
// First add the layer to the purgatory list, which makes sure it won't
// go away, then remove it from the main list (through a transaction).
- ssize_t err = removeLayer_l(layerBase);
+ ssize_t err = removeLayer_l(layer);
if (err >= 0) {
- mLayerPurgatory.add(layerBase);
+ mLayerPurgatory.add(layer);
}
- mLayersPendingRemoval.push(layerBase);
+ mLayersPendingRemoval.push(layer);
// it's possible that we don't find a layer, because it might
// have been destroyed already -- this is not technically an error
@@ -1873,7 +1866,7 @@
const layer_state_t& s)
{
uint32_t flags = 0;
- sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
+ sp<Layer> layer(client->getLayerUser(s.surface));
if (layer != 0) {
const uint32_t what = s.what;
if (what & layer_state_t::ePositionChanged) {
@@ -1937,7 +1930,7 @@
uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
- sp<LayerBaseClient> layer;
+ sp<Layer> layer;
sp<ISurface> surfaceHandle;
if (int32_t(w|h) < 0) {
@@ -1951,13 +1944,9 @@
case ISurfaceComposerClient::eFXSurfaceNormal:
layer = createNormalLayer(client, w, h, flags, format);
break;
- case ISurfaceComposerClient::eFXSurfaceBlur:
case ISurfaceComposerClient::eFXSurfaceDim:
layer = createDimLayer(client, w, h, flags);
break;
- case ISurfaceComposerClient::eFXSurfaceScreenshot:
- layer = createScreenshotLayer(client, w, h, flags);
- break;
}
if (layer != 0) {
@@ -2015,15 +2004,6 @@
return layer;
}
-sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
- const sp<Client>& client,
- uint32_t w, uint32_t h, uint32_t flags)
-{
- sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
- layer->setBuffers(w, h, PIXEL_FORMAT_RGBA_8888, flags);
- return layer;
-}
-
status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
{
/*
@@ -2037,7 +2017,7 @@
status_t err = NAME_NOT_FOUND;
Mutex::Autolock _l(mStateLock);
- sp<LayerBaseClient> layer = client->getLayerUser(handle);
+ sp<Layer> layer = client->getLayerUser(handle);
if (layer != 0) {
err = purgatorizeLayer_l(layer);
@@ -2048,11 +2028,11 @@
return err;
}
-status_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
+status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
{
// called by ~ISurface() when all references are gone
status_t err = NO_ERROR;
- sp<LayerBaseClient> l(layer.promote());
+ sp<Layer> l(layer.promote());
if (l != NULL) {
Mutex::Autolock _l(mStateLock);
err = removeLayer_l(l);
@@ -2269,7 +2249,7 @@
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
snprintf(buffer, SIZE, "%s\n", layer->getName().string());
result.append(buffer);
}
@@ -2294,7 +2274,7 @@
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
if (name == layer->getName()) {
layer->dumpStats(result, buffer, SIZE);
}
@@ -2314,7 +2294,7 @@
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
if (name.isEmpty() || (name == layer->getName())) {
layer->clearStats();
}
@@ -2370,7 +2350,7 @@
snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
result.append(buffer);
for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
+ const sp<Layer>& layer(currentLayers[i]);
layer->dump(result, buffer, SIZE);
}
@@ -2382,7 +2362,7 @@
snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
result.append(buffer);
for (size_t i=0 ; i<purgatorySize ; i++) {
- const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ const sp<Layer>& layer(mLayerPurgatory.itemAt(i));
layer->shortDump(result, buffer, SIZE);
}
@@ -2471,7 +2451,7 @@
alloc.dump(result);
}
-const Vector< sp<LayerBase> >&
+const Vector< sp<Layer> >&
SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) {
// Note: mStateLock is held here
return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ();
@@ -2728,10 +2708,10 @@
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
- const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
+ const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer(layers[i]);
+ const sp<Layer>& layer(layers[i]);
const uint32_t z = layer->drawingState().z;
if (z >= minLayerZ && z <= maxLayerZ) {
if (filtering) layer->setFiltering(true);
@@ -2740,6 +2720,9 @@
}
}
+ // compositionComplete is needed for older driver
+ hw->compositionComplete();
+
// and finishing things up...
if (eglSwapBuffers(mEGLDisplay, eglSurface) != EGL_TRUE) {
ALOGE("captureScreenImplLocked: eglSwapBuffers() failed 0x%4x",
@@ -2830,6 +2813,9 @@
glDeleteTextures(1, &tname);
+ DisplayDevice::makeCurrent(mEGLDisplay,
+ getDefaultDisplayDevice(), mEGLContext);
+
return result;
}
@@ -2896,15 +2882,15 @@
}
SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
- : SortedVector<sp<LayerBase> >(rhs) {
+ : SortedVector<sp<Layer> >(rhs) {
}
int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
const void* rhs) const
{
// sort layers per layer-stack, then by z-order and finally by sequence
- const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
- const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
+ const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
+ const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
uint32_t ls = l->currentState().layerStack;
uint32_t rs = r->currentState().layerStack;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d1221dc..241a7d6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -60,10 +60,7 @@
class EventThread;
class IGraphicBufferAlloc;
class Layer;
-class LayerBase;
-class LayerBaseClient;
class LayerDim;
-class LayerScreenshot;
class Surface;
// ---------------------------------------------------------------------------
@@ -125,15 +122,12 @@
// for debugging only
// TODO: this should be made accessible only to HWComposer
- const Vector< sp<LayerBase> >& getLayerSortedByZForHwcDisplay(int disp);
+ const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int disp);
private:
friend class Client;
friend class DisplayEventConnection;
- friend class LayerBase;
- friend class LayerBaseClient;
friend class Layer;
- friend class LayerScreenshot;
// We're reference counted, never destroy SurfaceFlinger directly
virtual ~SurfaceFlinger();
@@ -142,7 +136,7 @@
* Internal data structures
*/
- class LayerVector : public SortedVector<sp<LayerBase> > {
+ class LayerVector : public SortedVector< sp<Layer> > {
public:
LayerVector();
LayerVector(const LayerVector& rhs);
@@ -272,9 +266,6 @@
sp<LayerDim> createDimLayer(const sp<Client>& client,
uint32_t w, uint32_t h, uint32_t flags);
- sp<LayerScreenshot> createScreenshotLayer(const sp<Client>& client,
- uint32_t w, uint32_t h, uint32_t flags);
-
// called in response to the window-manager calling
// ISurfaceComposerClient::destroySurface()
// The specified layer is first placed in a purgatory list
@@ -284,17 +275,17 @@
// called when all clients have released all their references to
// this layer meaning it is entirely safe to destroy all
// resources associated to this layer.
- status_t onLayerDestroyed(const wp<LayerBaseClient>& layer);
+ status_t onLayerDestroyed(const wp<Layer>& layer);
// remove a layer from SurfaceFlinger immediately
- status_t removeLayer(const sp<LayerBase>& layer);
+ status_t removeLayer(const sp<Layer>& layer);
// add a layer to SurfaceFlinger
void addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
- const sp<LayerBaseClient>& lbc);
+ const sp<Layer>& lbc);
- status_t removeLayer_l(const sp<LayerBase>& layer);
- status_t purgatorizeLayer_l(const sp<LayerBase>& layer);
+ status_t removeLayer_l(const sp<Layer>& layer);
+ status_t purgatorizeLayer_l(const sp<Layer>& layer);
/* ------------------------------------------------------------------------
* Boot animation, on/off animations and screen capture
@@ -408,10 +399,10 @@
State mCurrentState;
volatile int32_t mTransactionFlags;
Condition mTransactionCV;
- SortedVector<sp<LayerBase> > mLayerPurgatory;
+ SortedVector< sp<Layer> > mLayerPurgatory;
bool mTransactionPending;
bool mAnimTransactionPending;
- Vector<sp<LayerBase> > mLayersPendingRemoval;
+ Vector< sp<Layer> > mLayersPendingRemoval;
// protected by mStateLock (but we could use another lock)
bool mLayersRemoved;
@@ -460,7 +451,7 @@
// protected by mDestroyedLayerLock;
mutable Mutex mDestroyedLayerLock;
- Vector<LayerBase const *> mDestroyedLayers;
+ Vector<Layer const *> mDestroyedLayers;
/* ------------------------------------------------------------------------
* Feature prototyping