Merge "Implement SurfaceFlinger's ANW on top of BufferQueue"
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index 65ccb8d..282e729 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -262,6 +262,7 @@
AKEYCODE_YEN = 216,
AKEYCODE_RO = 217,
AKEYCODE_KANA = 218,
+ AKEYCODE_ASSIST = 219,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index c5c2618..42aaa24 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -41,7 +41,12 @@
endif
ifeq ($(TARGET_BOARD_PLATFORM),msm7k)
-LOCAL_CFLAGS += -DADRENO130=1
+ LOCAL_CFLAGS += -DADRENO130=1
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
+ # see Loader.cpp for details
+ LOCAL_CFLAGS += -DSYSTEMUI_PBSIZE_HACK=1
endif
ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 0b1016c..9ee3686 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -81,6 +81,24 @@
// ----------------------------------------------------------------------------
+static char const * getProcessCmdline() {
+ long pid = getpid();
+ char procPath[128];
+ snprintf(procPath, 128, "/proc/%ld/cmdline", pid);
+ FILE * file = fopen(procPath, "r");
+ if (file) {
+ static char cmdline[256];
+ char *str = fgets(cmdline, sizeof(cmdline) - 1, file);
+ fclose(file);
+ if (str) {
+ return cmdline;
+ }
+ }
+ return NULL;
+}
+
+// ----------------------------------------------------------------------------
+
Loader::driver_t::driver_t(void* gles)
{
dso[0] = gles;
@@ -280,6 +298,35 @@
ALOGE_IF(!getProcAddress,
"can't find eglGetProcAddress() in %s", driver_absolute_path);
+#ifdef SYSTEMUI_PBSIZE_HACK
+#warning "SYSTEMUI_PBSIZE_HACK enabled"
+ /*
+ * TODO: replace SYSTEMUI_PBSIZE_HACK by something less hackish
+ *
+ * Here we adjust the PB size from its default value to 512KB which
+ * is the minimum acceptable for the systemui process.
+ * We do this on low-end devices only because it allows us to enable
+ * h/w acceleration in the systemui process while keeping the
+ * memory usage down.
+ *
+ * Obviously, this is the wrong place and wrong way to make this
+ * adjustment, but at the time of this writing this was the safest
+ * solution.
+ */
+ const char *cmdline = getProcessCmdline();
+ if (strstr(cmdline, "systemui")) {
+ void *imgegl = dlopen("/vendor/lib/libIMGegl.so", RTLD_LAZY);
+ if (imgegl) {
+ unsigned int *PVRDefaultPBS =
+ (unsigned int *)dlsym(imgegl, "PVRDefaultPBS");
+ if (PVRDefaultPBS) {
+ ALOGD("setting default PBS to 512KB, was %d KB", *PVRDefaultPBS / 1024);
+ *PVRDefaultPBS = 512*1024;
+ }
+ }
+ }
+#endif
+
egl_t* egl = &cnx->egl;
__eglMustCastToProperFunctionPointerType* curr =
(__eglMustCastToProperFunctionPointerType*)egl;
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index a46aa38..80072ab 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -263,7 +263,13 @@
Mutex::Autolock _l(lock);
if (refs == 0) {
- return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
+ /*
+ * From the EGL spec (3.2):
+ * "Termination of a display that has already been terminated,
+ * (...), is allowed, but the only effect of such a call is
+ * to return EGL_TRUE (...)
+ */
+ return EGL_TRUE;
}
// this is specific to Android, display termination is ref-counted.
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp
index 45dbb43..91b291e 100644
--- a/opengl/libs/GLES_trace/src/gltrace_context.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp
@@ -119,7 +119,7 @@
const size_t DEFAULT_BUFFER_SIZE = 8192;
BufferedOutputStream *stream = new BufferedOutputStream(mStream, DEFAULT_BUFFER_SIZE);
- GLTraceContext *traceContext = new GLTraceContext(id, this, stream);
+ GLTraceContext *traceContext = new GLTraceContext(id, version, this, stream);
mPerContextState[eglContext] = traceContext;
return traceContext;
@@ -129,8 +129,10 @@
return mPerContextState[c];
}
-GLTraceContext::GLTraceContext(int id, GLTraceState *state, BufferedOutputStream *stream) :
+GLTraceContext::GLTraceContext(int id, int version, GLTraceState *state,
+ BufferedOutputStream *stream) :
mId(id),
+ mVersion(version),
mState(state),
mBufferedOutputStream(stream),
mElementArrayBuffers(DefaultKeyedVector<GLuint, ElementArrayBuffer*>(NULL))
@@ -143,6 +145,10 @@
return mId;
}
+int GLTraceContext::getVersion() {
+ return mVersion;
+}
+
GLTraceState *GLTraceContext::getGlobalTraceState() {
return mState;
}
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.h b/opengl/libs/GLES_trace/src/gltrace_context.h
index 323cfdc..4c38bba 100644
--- a/opengl/libs/GLES_trace/src/gltrace_context.h
+++ b/opengl/libs/GLES_trace/src/gltrace_context.h
@@ -50,6 +50,7 @@
/** GL Trace Context info associated with each EGLContext */
class GLTraceContext {
int mId; /* unique context id */
+ int mVersion; /* GL version, e.g: egl_connection_t::GLESv2_INDEX */
GLTraceState *mState; /* parent GL Trace state (for per process GL Trace State Info) */
void *fbcontents; /* memory area to read framebuffer contents */
@@ -65,8 +66,9 @@
public:
gl_hooks_t *hooks;
- GLTraceContext(int id, GLTraceState *state, BufferedOutputStream *stream);
+ GLTraceContext(int id, int version, GLTraceState *state, BufferedOutputStream *stream);
int getId();
+ int getVersion();
GLTraceState *getGlobalTraceState();
void getCompressedFB(void **fb, unsigned *fbsize,
unsigned *fbwidth, unsigned *fbheight,
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index 3597b26..1bd790e 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -15,6 +15,7 @@
*/
#include <cutils/log.h>
+#include <EGL/egldefs.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
@@ -592,6 +593,11 @@
}
void trace_VertexAttribPointerDataForGlDrawArrays(GLTraceContext *context, GLMessage *glmsg) {
+ if (context->getVersion() == egl_connection_t::GLESv1_INDEX) {
+ // only supported for GLES2 and above
+ return;
+ }
+
/* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */
GLsizei count = glmsg->args(2).intvalue(0);
@@ -604,6 +610,11 @@
void trace_VertexAttribPointerDataForGlDrawElements(GLTraceContext *context, GLMessage *glmsg,
GLvoid *indices) {
+ if (context->getVersion() == egl_connection_t::GLESv1_INDEX) {
+ // only supported for GLES2 and above
+ return;
+ }
+
/* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */
GLsizei count = glmsg->args(1).intvalue(0);
GLenum type = glmsg->args(2).intvalue(0);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 65763db..ce63ee7 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -43,6 +43,19 @@
namespace android {
// ---------------------------------------------------------------------------
+struct HWComposer::cb_context {
+ struct callbacks : public hwc_procs_t {
+ // these are here to facilitate the transition when adding
+ // new callbacks (an implementation can check for NULL before
+ // calling a new callback).
+ void (*zero[4])(void);
+ };
+ callbacks procs;
+ HWComposer* hwc;
+};
+
+// ---------------------------------------------------------------------------
+
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler,
@@ -51,6 +64,7 @@
mModule(0), mHwc(0), mList(0), mCapacity(0),
mNumOVLayers(0), mNumFBLayers(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
+ mCBContext(new cb_context),
mEventHandler(handler),
mRefreshPeriod(refreshPeriod),
mVSyncCount(0), mDebugForceFakeVSync(false)
@@ -68,11 +82,11 @@
HWC_HARDWARE_COMPOSER, strerror(-err));
if (err == 0) {
if (mHwc->registerProcs) {
- mCBContext.hwc = this;
- mCBContext.procs.invalidate = &hook_invalidate;
- mCBContext.procs.vsync = &hook_vsync;
- mHwc->registerProcs(mHwc, &mCBContext.procs);
- memset(mCBContext.procs.zero, 0, sizeof(mCBContext.procs.zero));
+ mCBContext->hwc = this;
+ mCBContext->procs.invalidate = &hook_invalidate;
+ mCBContext->procs.vsync = &hook_vsync;
+ mHwc->registerProcs(mHwc, &mCBContext->procs);
+ memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
}
if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
if (mDebugForceFakeVSync) {
@@ -102,6 +116,7 @@
if (mHwc) {
hwc_close(mHwc);
}
+ delete mCBContext;
}
status_t HWComposer::initCheck() const {
@@ -230,10 +245,117 @@
return mList ? mList->numHwLayers : 0;
}
-hwc_layer_t* HWComposer::getLayers() const {
- return mList ? mList->hwLayers : 0;
+/*
+ * Helper template to implement a concrete HWCLayer
+ * This holds the pointer to the concrete hwc layer type
+ * and implements the "iterable" side of HWCLayer.
+ */
+template<typename CONCRETE, typename HWCTYPE>
+class Iterable : public HWComposer::HWCLayer {
+protected:
+ HWCTYPE* const mLayerList;
+ HWCTYPE* mCurrentLayer;
+ Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
+ inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
+ inline HWCTYPE* getLayer() { return mCurrentLayer; }
+ virtual ~Iterable() { }
+private:
+ // returns a copy of ourselves
+ virtual HWComposer::HWCLayer* dup() {
+ return new CONCRETE( static_cast<const CONCRETE&>(*this) );
+ }
+ virtual status_t setLayer(size_t index) {
+ mCurrentLayer = &mLayerList[index];
+ return NO_ERROR;
+ }
+};
+
+/*
+ * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
+ * This implements the HWCLayer side of HWCIterableLayer.
+ */
+class HWCLayerVersion03 : public Iterable<HWCLayerVersion03, hwc_layer_t> {
+public:
+ HWCLayerVersion03(hwc_layer_t* layer)
+ : Iterable<HWCLayerVersion03, hwc_layer_t>(layer) { }
+
+ virtual int32_t getCompositionType() const {
+ return getLayer()->compositionType;
+ }
+ virtual uint32_t getHints() const {
+ return getLayer()->hints;
+ }
+
+ virtual void setDefaultState() {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->hints = 0;
+ getLayer()->flags = HWC_SKIP_LAYER;
+ getLayer()->transform = 0;
+ getLayer()->blending = HWC_BLENDING_NONE;
+ getLayer()->visibleRegionScreen.numRects = 0;
+ getLayer()->visibleRegionScreen.rects = NULL;
+ }
+ virtual void setSkip(bool skip) {
+ if (skip) {
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ } else {
+ getLayer()->flags &= ~HWC_SKIP_LAYER;
+ }
+ }
+ virtual void setBlending(uint32_t blending) {
+ getLayer()->blending = blending;
+ }
+ virtual void setTransform(uint32_t transform) {
+ getLayer()->transform = transform;
+ }
+ virtual void setFrame(const Rect& frame) {
+ reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
+ }
+ virtual void setCrop(const Rect& crop) {
+ reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
+ }
+ virtual void setVisibleRegionScreen(const Region& reg) {
+ getLayer()->visibleRegionScreen.rects =
+ reinterpret_cast<hwc_rect_t const *>(
+ reg.getArray(&getLayer()->visibleRegionScreen.numRects));
+ }
+ virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
+ if (buffer == 0 || buffer->handle == 0) {
+ getLayer()->compositionType = HWC_FRAMEBUFFER;
+ getLayer()->flags |= HWC_SKIP_LAYER;
+ getLayer()->handle = 0;
+ } else {
+ getLayer()->handle = buffer->handle;
+ }
+ }
+};
+
+/*
+ * returns an iterator initialized at a given index in the layer list
+ */
+HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
+ if (!mList || index > mList->numHwLayers) {
+ return LayerListIterator();
+ }
+ return LayerListIterator(new HWCLayerVersion03(mList->hwLayers), index);
}
+/*
+ * returns an iterator on the beginning of the layer list
+ */
+HWComposer::LayerListIterator HWComposer::begin() {
+ return getLayerIterator(0);
+}
+
+/*
+ * returns an iterator on the end of the layer list
+ */
+HWComposer::LayerListIterator HWComposer::end() {
+ return getLayerIterator(getNumLayers());
+}
+
+
+
void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
if (mHwc && mList) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index aada3cd..cafa247 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -22,7 +22,7 @@
#include <EGL/egl.h>
-#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
#include <utils/StrongPointer.h>
#include <utils/Vector.h>
@@ -31,12 +31,17 @@
const struct timespec *request,
struct timespec *remain);
+struct hwc_composer_device;
+struct hwc_layer_list;
+struct hwc_procs;
+
namespace android {
// ---------------------------------------------------------------------------
class String8;
class SurfaceFlinger;
class LayerBase;
+class GraphicBuffer;
class HWComposer
{
@@ -57,9 +62,6 @@
// tells the HAL what the framebuffer is
void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
- // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
- status_t createWorkList(size_t numLayers);
-
// Asks the HAL what it can do
status_t prepare() const;
@@ -72,14 +74,109 @@
// release hardware resources
status_t release() const;
+ // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
+ status_t createWorkList(size_t numLayers);
+
// get the layer array created by createWorkList()
size_t getNumLayers() const;
- hwc_layer_t* getLayers() const;
// get number of layers of the given type as updated in prepare().
// type is HWC_OVERLAY or HWC_FRAMEBUFFER
size_t getLayerCount(int type) const;
+ // needed forward declarations
+ class LayerListIterator;
+
+ /*
+ * Interface to hardware composer's layers functionality.
+ * This abstracts the HAL interface to layers which can evolve in
+ * incompatible ways from one release to another.
+ * The idea is that we could extend this interface as we add
+ * features to h/w composer.
+ */
+ class HWCLayerInterface {
+ protected:
+ virtual ~HWCLayerInterface() { }
+ public:
+ virtual int32_t getCompositionType() const = 0;
+ virtual uint32_t getHints() const = 0;
+ virtual void setDefaultState() = 0;
+ virtual void setSkip(bool skip) = 0;
+ virtual void setBlending(uint32_t blending) = 0;
+ virtual void setTransform(uint32_t transform) = 0;
+ virtual void setFrame(const Rect& frame) = 0;
+ virtual void setCrop(const Rect& crop) = 0;
+ virtual void setVisibleRegionScreen(const Region& reg) = 0;
+ virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
+ };
+
+ /*
+ * Interface used to implement an iterator to a list
+ * of HWCLayer.
+ */
+ class HWCLayer : public HWCLayerInterface {
+ friend class LayerListIterator;
+ // select the layer at the given index
+ virtual status_t setLayer(size_t index) = 0;
+ virtual HWCLayer* dup() = 0;
+ static HWCLayer* copy(HWCLayer *rhs) {
+ return rhs ? rhs->dup() : NULL;
+ }
+ protected:
+ virtual ~HWCLayer() { }
+ };
+
+ /*
+ * Iterator through a HWCLayer list.
+ * This behaves more or less like a forward iterator.
+ */
+ class LayerListIterator {
+ friend struct HWComposer;
+ HWCLayer* const mLayerList;
+ size_t mIndex;
+
+ LayerListIterator() : mLayerList(NULL), mIndex(0) { }
+
+ LayerListIterator(HWCLayer* layer, size_t index)
+ : mLayerList(layer), mIndex(index) { }
+
+ // we don't allow assignment, because we don't need it for now
+ LayerListIterator& operator = (const LayerListIterator& rhs);
+
+ public:
+ // copy operators
+ LayerListIterator(const LayerListIterator& rhs)
+ : mLayerList(HWCLayer::copy(rhs.mLayerList)), mIndex(rhs.mIndex) {
+ }
+
+ ~LayerListIterator() { delete mLayerList; }
+
+ // pre-increment
+ LayerListIterator& operator++() {
+ mLayerList->setLayer(++mIndex);
+ return *this;
+ }
+
+ // dereference
+ HWCLayerInterface& operator * () { return *mLayerList; }
+ HWCLayerInterface* operator -> () { return mLayerList; }
+
+ // comparison
+ bool operator == (const LayerListIterator& rhs) const {
+ return mIndex == rhs.mIndex;
+ }
+ bool operator != (const LayerListIterator& rhs) const {
+ return !operator==(rhs);
+ }
+ };
+
+ // Returns an iterator to the beginning of the layer list
+ LayerListIterator begin();
+
+ // Returns an iterator to the end of the layer list
+ LayerListIterator end();
+
+
// Events handling ---------------------------------------------------------
enum {
@@ -111,18 +208,9 @@
const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;
private:
+ LayerListIterator getLayerIterator(size_t index);
- struct callbacks : public hwc_procs_t {
- // these are here to facilitate the transition when adding
- // new callbacks (an implementation can check for NULL before
- // calling a new callback).
- void (*zero[4])(void);
- };
-
- struct cb_context {
- callbacks procs;
- HWComposer* hwc;
- };
+ struct cb_context;
static void hook_invalidate(struct hwc_procs* procs);
static void hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp);
@@ -132,14 +220,14 @@
sp<SurfaceFlinger> mFlinger;
hw_module_t const* mModule;
- hwc_composer_device_t* mHwc;
- hwc_layer_list_t* mList;
+ struct hwc_composer_device* mHwc;
+ struct hwc_layer_list* mList;
size_t mCapacity;
mutable size_t mNumOVLayers;
mutable size_t mNumFBLayers;
- hwc_display_t mDpy;
- hwc_surface_t mSur;
- cb_context mCBContext;
+ EGLDisplay mDpy;
+ EGLSurface mSur;
+ cb_context* mCBContext;
EventHandler& mEventHandler;
nsecs_t mRefreshPeriod;
size_t mVSyncCount;
@@ -147,7 +235,6 @@
bool mDebugForceFakeVSync;
};
-
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4062340..890bcb4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -259,16 +259,17 @@
return crop;
}
-void Layer::setGeometry(hwc_layer_t* hwcl)
+void Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
{
- LayerBaseClient::setGeometry(hwcl);
+ LayerBaseClient::setGeometry(layer);
- hwcl->flags &= ~HWC_SKIP_LAYER;
+ // enable this layer
+ layer.setSkip(false);
// we can't do alpha-fade with the hwc HAL
const State& s(drawingState());
if (s.alpha < 0xFF) {
- hwcl->flags = HWC_SKIP_LAYER;
+ layer.setSkip(true);
}
/*
@@ -288,29 +289,18 @@
// we can only handle simple transformation
if (finalTransform & Transform::ROT_INVALID) {
- hwcl->flags = HWC_SKIP_LAYER;
+ layer.setSkip(true);
} else {
- hwcl->transform = finalTransform;
+ layer.setTransform(finalTransform);
}
-
- Rect crop = computeBufferCrop();
- hwcl->sourceCrop.left = crop.left;
- hwcl->sourceCrop.top = crop.top;
- hwcl->sourceCrop.right = crop.right;
- hwcl->sourceCrop.bottom = crop.bottom;
+ layer.setCrop(computeBufferCrop());
}
-void Layer::setPerFrameData(hwc_layer_t* hwcl) {
+void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
const sp<GraphicBuffer>& buffer(mActiveBuffer);
- if (buffer == NULL) {
- // this can happen if the client never drew into this layer yet,
- // or if we ran out of memory. In that case, don't let
- // HWC handle it.
- hwcl->flags |= HWC_SKIP_LAYER;
- hwcl->handle = NULL;
- } else {
- hwcl->handle = buffer->handle;
- }
+ // NOTE: buffer can be NULL if the client never drew into this
+ // layer yet, or if we ran out of memory
+ layer.setBuffer(buffer);
}
void Layer::onDraw(const Region& clip) const
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 393599f..7a164aa 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -64,8 +64,8 @@
bool isFixedSize() const;
// LayerBase interface
- virtual void setGeometry(hwc_layer_t* hwcl);
- virtual void setPerFrameData(hwc_layer_t* hwcl);
+ virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
+ virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
virtual void onDraw(const Region& clip) const;
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual void lockPageFlip(bool& recomputeVisibleRegions);
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 16bac8f..fe15dc9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -281,48 +281,34 @@
const Transform& planeTransform, Region& outDirtyRegion) {
}
-void LayerBase::setGeometry(hwc_layer_t* hwcl)
+void LayerBase::setGeometry(HWComposer::HWCLayerInterface& layer)
{
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->hints = 0;
- hwcl->flags = HWC_SKIP_LAYER;
- hwcl->transform = 0;
- hwcl->blending = HWC_BLENDING_NONE;
+ 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) {
- hwcl->flags = HWC_SKIP_LAYER;
+ layer.setTransform(0);
} else {
- hwcl->transform = finalTransform;
+ layer.setTransform(finalTransform);
}
if (!isOpaque()) {
- hwcl->blending = mPremultipliedAlpha ?
- HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
+ layer.setBlending(mPremultipliedAlpha ?
+ HWC_BLENDING_PREMULT :
+ HWC_BLENDING_COVERAGE);
}
// scaling is already applied in mTransformedBounds
- hwcl->displayFrame.left = mTransformedBounds.left;
- hwcl->displayFrame.top = mTransformedBounds.top;
- hwcl->displayFrame.right = mTransformedBounds.right;
- hwcl->displayFrame.bottom = mTransformedBounds.bottom;
- hwcl->visibleRegionScreen.rects =
- reinterpret_cast<hwc_rect_t const *>(
- visibleRegionScreen.getArray(
- &hwcl->visibleRegionScreen.numRects));
-
- hwcl->sourceCrop.left = 0;
- hwcl->sourceCrop.top = 0;
- hwcl->sourceCrop.right = mTransformedBounds.width();
- hwcl->sourceCrop.bottom = mTransformedBounds.height();
+ layer.setFrame(mTransformedBounds);
+ layer.setVisibleRegionScreen(visibleRegionScreen);
+ layer.setCrop(mTransformedBounds.getBounds());
}
-void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->handle = NULL;
+void LayerBase::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
+ layer.setBuffer(0);
}
void LayerBase::setFiltering(bool filtering)
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index c547a40..4d5d1e4 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -32,8 +32,6 @@
#include <private/gui/LayerState.h>
-#include <hardware/hwcomposer.h>
-
#include "DisplayHardware/DisplayHardware.h"
#include "Transform.h"
@@ -116,8 +114,8 @@
virtual const char* getTypeId() const { return "LayerBase"; }
- virtual void setGeometry(hwc_layer_t* hwcl);
- virtual void setPerFrameData(hwc_layer_t* hwcl);
+ virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
+ virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
/**
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 61b5f71..e2c7aed 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -800,12 +800,13 @@
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
const size_t count = currentLayers.size();
hwc.createWorkList(count);
- hwc_layer_t* const cur(hwc.getLayers());
- for (size_t i=0 ; cur && i<count ; i++) {
- currentLayers[i]->setGeometry(&cur[i]);
+
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+ currentLayers[i]->setGeometry(*cur);
if (mDebugDisableHWC || mDebugRegion) {
- cur[i].compositionType = HWC_FRAMEBUFFER;
- cur[i].flags |= HWC_SKIP_LAYER;
+ cur->setSkip(true);
}
}
}
@@ -859,8 +860,10 @@
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
- hwc_layer_t* const cur(hwc.getLayers());
- if (!cur) {
+
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ if (cur == end) {
return;
}
@@ -880,9 +883,9 @@
* update the per-frame h/w composer data for each layer
* and build the transparent region of the FB
*/
- for (size_t i=0 ; i<count ; i++) {
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<LayerBase>& layer(layers[i]);
- layer->setPerFrameData(&cur[i]);
+ layer->setPerFrameData(*cur);
}
status_t err = hwc.prepare();
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
@@ -892,10 +895,11 @@
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
- hwc_layer_t* const cur(hwc.getLayers());
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
- if (!cur || fbLayerCount) {
+ if (cur==end || fbLayerCount) {
// Never touch the framebuffer if we don't have any framebuffer layers
if (hwc.getLayerCount(HWC_OVERLAY)) {
@@ -920,13 +924,12 @@
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
const size_t count = layers.size();
-
- for (size_t i=0 ; i<count ; i++) {
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
- if (cur && (cur[i].compositionType == HWC_OVERLAY)) {
- if (i && (cur[i].hints & HWC_HINT_CLEAR_FB)
+ if (cur->getCompositionType() == HWC_OVERLAY) {
+ if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
&& layer->isOpaque()) {
// never clear the very first layer since we're
// guaranteed the FB is already cleared