summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r--services/surfaceflinger/Android.mk3
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.cpp22
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.h8
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp99
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h68
-rw-r--r--services/surfaceflinger/Layer.cpp57
-rw-r--r--services/surfaceflinger/Layer.h2
-rw-r--r--services/surfaceflinger/LayerBase.cpp9
-rw-r--r--services/surfaceflinger/LayerBase.h6
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp143
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
11 files changed, 388 insertions, 31 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index a14bfb5..e4825d0 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -5,6 +5,7 @@ LOCAL_SRC_FILES:= \
clz.cpp.arm \
DisplayHardware/DisplayHardware.cpp \
DisplayHardware/DisplayHardwareBase.cpp \
+ DisplayHardware/HWComposer.cpp \
BlurFilter.cpp.arm \
GLExtensions.cpp \
Layer.cpp \
@@ -21,7 +22,7 @@ LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
ifeq ($(TARGET_BOARD_PLATFORM), omap3)
- LOCAL_CFLAGS += -DNO_RGBX_8888
+ LOCAL_CFLAGS += -DNO_RGBX_8888 -DHAS_PUSH_BUFFERS
endif
# need "-lrt" on Linux simulator to pick up clock_gettime
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 2eac0a8..166c528 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -36,11 +36,11 @@
#include "DisplayHardware/DisplayHardware.h"
-#include <hardware/copybit.h>
#include <hardware/overlay.h>
#include <hardware/gralloc.h>
#include "GLExtensions.h"
+#include "HWComposer.h"
using namespace android;
@@ -76,7 +76,7 @@ DisplayHardware::DisplayHardware(
const sp<SurfaceFlinger>& flinger,
uint32_t dpy)
: DisplayHardwareBase(flinger, dpy),
- mFlags(0)
+ mFlags(0), mHwc(0)
{
init(dpy);
}
@@ -262,6 +262,17 @@ void DisplayHardware::init(uint32_t dpy)
// Unbind the context from this thread
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+
+ // initialize the H/W composer
+ mHwc = new HWComposer();
+ if (mHwc->initCheck() == NO_ERROR) {
+ mHwc->setFrameBuffer(mDisplay, mSurface);
+ }
+}
+
+HWComposer& DisplayHardware::getHwComposer() const {
+ return *mHwc;
}
/*
@@ -317,7 +328,12 @@ void DisplayHardware::flip(const Region& dirty) const
}
mPageFlipCount++;
- eglSwapBuffers(dpy, surface);
+
+ if (mHwc->initCheck() == NO_ERROR) {
+ mHwc->commit();
+ } else {
+ eglSwapBuffers(dpy, surface);
+ }
checkEGLErrors("eglSwapBuffers");
// for debugging
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 66bf521..f2cfd2d 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -34,12 +34,11 @@
#include "DisplayHardware/DisplayHardwareBase.h"
struct overlay_control_device_t;
-struct framebuffer_device_t;
-struct copybit_image_t;
namespace android {
class FramebufferNativeWindow;
+class HWComposer;
class DisplayHardware : public DisplayHardwareBase
{
@@ -80,6 +79,9 @@ public:
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
+
+ // Hardware Composer
+ HWComposer& getHwComposer() const;
status_t compositionComplete() const;
@@ -107,6 +109,8 @@ private:
GLint mMaxViewportDims;
GLint mMaxTextureSize;
+ HWComposer* mHwc;
+
sp<FramebufferNativeWindow> mNativeWindow;
overlay_control_device_t* mOverlayEngine;
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
new file mode 100644
index 0000000..0291d78
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 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 <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include <hardware/hardware.h>
+
+#include <cutils/log.h>
+
+#include <EGL/egl.h>
+
+#include "HWComposer.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+HWComposer::HWComposer()
+ : mModule(0), mHwc(0), mList(0), mCapacity(0),
+ mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
+{
+ int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
+ LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
+ if (err == 0) {
+ err = hwc_open(mModule, &mHwc);
+ LOGE_IF(err, "%s device failed to initialize (%s)",
+ HWC_HARDWARE_COMPOSER, strerror(-err));
+ }
+}
+
+HWComposer::~HWComposer() {
+ free(mList);
+ if (mHwc) {
+ hwc_close(mHwc);
+ }
+}
+
+status_t HWComposer::initCheck() const {
+ return mHwc ? NO_ERROR : NO_INIT;
+}
+
+void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
+ mDpy = (hwc_display_t)dpy;
+ mSur = (hwc_surface_t)sur;
+}
+
+status_t HWComposer::createWorkList(size_t numLayers) {
+ if (mHwc) {
+ if (!mList || mCapacity < numLayers) {
+ free(mList);
+ size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
+ mList = (hwc_layer_list_t*)malloc(size);
+ mCapacity = numLayers;
+ }
+ mList->flags = HWC_GEOMETRY_CHANGED;
+ mList->numHwLayers = numLayers;
+ }
+ return NO_ERROR;
+}
+
+status_t HWComposer::prepare() const {
+ int err = mHwc->prepare(mHwc, mList);
+ return (status_t)err;
+}
+
+status_t HWComposer::commit() const {
+ int err = mHwc->set(mHwc, mDpy, mSur, mList);
+ mList->flags &= ~HWC_GEOMETRY_CHANGED;
+ return (status_t)err;
+}
+
+size_t HWComposer::getNumLayers() const {
+ return mList ? mList->numHwLayers : 0;
+}
+
+hwc_layer_t* HWComposer::getLayers() const {
+ return mList ? mList->hwLayers : 0;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
new file mode 100644
index 0000000..c5d5c2b
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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_SF_HWCOMPOSER_H
+#define ANDROID_SF_HWCOMPOSER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+
+#include <hardware/hwcomposer.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class HWComposer
+{
+public:
+
+ HWComposer();
+ ~HWComposer();
+
+ status_t initCheck() const;
+
+ // tells the HAL what the framebuffer is
+ void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
+
+ // create a work list for numLayers layer
+ status_t createWorkList(size_t numLayers);
+
+ // Asks the HAL what it can do
+ status_t prepare() const;
+
+ // commits the list
+ status_t commit() const;
+
+
+ size_t getNumLayers() const;
+ hwc_layer_t* getLayers() const;
+
+private:
+ hw_module_t const* mModule;
+ hwc_composer_device_t* mHwc;
+ hwc_layer_list_t* mList;
+ size_t mCapacity;
+ hwc_display_t mDpy;
+ hwc_surface_t mSur;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 629d993..3720e1669 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -35,6 +35,7 @@
#include "Layer.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
+#include "DisplayHardware/HWComposer.h"
#define DEBUG_RESIZE 0
@@ -177,6 +178,62 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
return NO_ERROR;
}
+void Layer::setGeometry(hwc_layer_t* hwcl)
+{
+ hwcl->compositionType = HWC_FRAMEBUFFER;
+ hwcl->hints = 0;
+ hwcl->flags = 0;
+ hwcl->transform = 0;
+ hwcl->blending = HWC_BLENDING_NONE;
+
+ // we can't do alpha-fade with the hwc HAL
+ const State& s(drawingState());
+ if (s.alpha < 0xFF) {
+ hwcl->flags = HWC_SKIP_LAYER;
+ return;
+ }
+
+ // we can only handle simple transformation
+ if (mOrientation & Transform::ROT_INVALID) {
+ hwcl->flags = HWC_SKIP_LAYER;
+ return;
+ }
+
+ hwcl->transform = mOrientation;
+
+ if (needsBlending()) {
+ hwcl->blending = mPremultipliedAlpha ?
+ HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
+ }
+
+ 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));
+}
+
+void Layer::setPerFrameData(hwc_layer_t* hwcl) {
+ sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
+ if (buffer == NULL) {
+ // this situation can happen if we ran out of memory for instance.
+ // not much we can do. continue to use whatever texture was bound
+ // to this context.
+ hwcl->handle = NULL;
+ return;
+ }
+ hwcl->handle = const_cast<native_handle_t*>(buffer->handle);
+ // TODO: set the crop value properly
+ hwcl->sourceCrop.left = 0;
+ hwcl->sourceCrop.top = 0;
+ hwcl->sourceCrop.right = buffer->width;
+ hwcl->sourceCrop.bottom = buffer->height;
+}
+
void Layer::reloadTexture(const Region& dirty)
{
sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e1d283b..188da6a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -68,6 +68,8 @@ public:
bool isFixedSize() const;
// LayerBase interface
+ virtual void setGeometry(hwc_layer_t* hwcl);
+ virtual void setPerFrameData(hwc_layer_t* hwcl);
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 91ac915..043d54d 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -307,6 +307,15 @@ void LayerBase::drawRegion(const Region& reg) const
}
}
+void LayerBase::setGeometry(hwc_layer_t* hwcl) {
+ hwcl->flags |= HWC_SKIP_LAYER;
+}
+
+void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
+ hwcl->compositionType = HWC_FRAMEBUFFER;
+ hwcl->handle = NULL;
+}
+
void LayerBase::draw(const Region& clip) const
{
// reset GL state
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 22bf857..dd1cd05 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -35,6 +35,8 @@
#include <pixelflinger/pixelflinger.h>
+#include <hardware/hwcomposer.h>
+
#include "Transform.h"
namespace android {
@@ -108,6 +110,10 @@ public:
virtual const char* getTypeId() const { return "LayerBase"; }
+ virtual void setGeometry(hwc_layer_t* hwcl);
+
+ virtual void setPerFrameData(hwc_layer_t* hwcl);
+
/**
* draw - performs some global clipping optimizations
* and calls onDraw().
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 637ae48..a78d9b9 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -52,6 +52,7 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
+#include "DisplayHardware/HWComposer.h"
/* ideally AID_GRAPHICS would be in a semi-public header
* or there would be a way to map a user/group name to its id
@@ -76,6 +77,7 @@ SurfaceFlinger::SurfaceFlinger()
mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
mDump("android.permission.DUMP"),
mVisibleRegionsDirty(false),
+ mHwWorkListDirty(false),
mDeferReleaseConsole(false),
mFreezeDisplay(false),
mFreezeCount(0),
@@ -163,7 +165,7 @@ void SurfaceFlinger::bootFinished()
{
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
- LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
+ LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
mBootFinished = true;
property_set("ctl.stop", "bootanim");
}
@@ -199,10 +201,10 @@ status_t SurfaceFlinger::readyToRun()
mServerHeap = new MemoryHeapBase(4096,
MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
-
+
mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
-
+
new(mServerCblk) surface_flinger_cblk_t;
// initialize primary screen
@@ -231,7 +233,7 @@ status_t SurfaceFlinger::readyToRun()
// Initialize OpenGL|ES
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glPixelStorei(GL_PACK_ALIGNMENT, 4);
+ glPixelStorei(GL_PACK_ALIGNMENT, 4);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_SCISSOR_TEST);
glShadeModel(GL_FLAT);
@@ -265,7 +267,7 @@ status_t SurfaceFlinger::readyToRun()
// start boot animation
property_set("ctl.start", "bootanim");
-
+
return NO_ERROR;
}
@@ -368,6 +370,11 @@ bool SurfaceFlinger::threadLoop()
// post surfaces (if needed)
handlePageFlip();
+ if (UNLIKELY(mHwWorkListDirty)) {
+ // build the h/w work list
+ handleWorkList();
+ }
+
const DisplayHardware& hw(graphicPlane(0).displayHardware());
if (LIKELY(hw.canDraw() && !isFrozen())) {
// repaint the framebuffer (if needed)
@@ -443,6 +450,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
handleTransactionLocked(transactionFlags, ditchedLayers);
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
+ mHwWorkListDirty = true;
// here the transaction has been committed
}
@@ -450,6 +458,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
* Clean-up all layers that went away
* (do this without the lock held)
*/
+
const size_t count = ditchedLayers.size();
for (size_t i=0 ; i<count ; i++) {
if (ditchedLayers[i] != 0) {
@@ -653,7 +662,7 @@ void SurfaceFlinger::computeVisibleRegions(
// Update aboveOpaqueLayers for next (lower) layer
aboveOpaqueLayers.orSelf(opaqueRegion);
-
+
// Store the visible region is screen space
layer->setVisibleRegion(visibleRegion);
layer->setCoveredRegion(coveredRegion);
@@ -683,8 +692,8 @@ void SurfaceFlinger::commitTransaction()
void SurfaceFlinger::handlePageFlip()
{
bool visibleRegions = mVisibleRegionsDirty;
- LayerVector& currentLayers = const_cast<LayerVector&>(
- mDrawingState.layersSortedByZ);
+ LayerVector& currentLayers(
+ const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
visibleRegions |= lockPageFlip(currentLayers);
const DisplayHardware& hw = graphicPlane(0).displayHardware();
@@ -707,6 +716,7 @@ void SurfaceFlinger::handlePageFlip()
mWormholeRegion = screenRegion.subtract(opaqueRegion);
mVisibleRegionsDirty = false;
+ mHwWorkListDirty = true;
}
unlockPageFlip(currentLayers);
@@ -737,6 +747,20 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
}
}
+void SurfaceFlinger::handleWorkList()
+{
+ mHwWorkListDirty = false;
+ HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
+ if (hwc.initCheck() == NO_ERROR) {
+ 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]);
+ }
+ }
+}
void SurfaceFlinger::handleRepaint()
{
@@ -757,8 +781,8 @@ void SurfaceFlinger::handleRepaint()
glLoadIdentity();
uint32_t flags = hw.getFlags();
- if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
- (flags & DisplayHardware::BUFFER_PRESERVED))
+ if ((flags & DisplayHardware::SWAP_RECTANGLE) ||
+ (flags & DisplayHardware::BUFFER_PRESERVED))
{
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
// takes a rectangle, we must make sure to update that whole
@@ -801,9 +825,72 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
// draw something...
drawWormhole();
}
+
+ status_t err = NO_ERROR;
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
+ size_t count = layers.size();
+
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ HWComposer& hwc(hw.getHwComposer());
+ hwc_layer_t* const cur(hwc.getLayers());
+
+ LOGE_IF(cur && hwc.getNumLayers() != count,
+ "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
+ hwc.getNumLayers(), count);
+
+ // just to be extra-safe, use the smallest count
+ if (hwc.initCheck() == NO_ERROR) {
+ count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
+ }
+
+ /*
+ * update the per-frame h/w composer data for each layer
+ * and build the transparent region of the FB
+ */
+ Region transparent;
+ if (cur) {
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(layers[i]);
+ layer->setPerFrameData(&cur[i]);
+ if (cur[i].hints & HWC_HINT_CLEAR_FB) {
+ if (!(layer->needsBlending())) {
+ transparent.orSelf(layer->visibleRegionScreen);
+ }
+ }
+ }
+ err = hwc.prepare();
+ LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
+ }
+
+ /*
+ * clear the area of the FB that need to be transparent
+ */
+ transparent.andSelf(dirty);
+ if (!transparent.isEmpty()) {
+ glClearColor(0,0,0,0);
+ Region::const_iterator it = transparent.begin();
+ Region::const_iterator const end = transparent.end();
+ const int32_t height = hw.getHeight();
+ while (it != end) {
+ const Rect& r(*it++);
+ const GLint sy = height - (r.top + r.height());
+ glScissor(r.left, sy, r.width(), r.height());
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ }
+
+
+ /*
+ * and then, render the layers targeted at the framebuffer
+ */
+ for (size_t i=0 ; i<count ; i++) {
+ if (cur) {
+ if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
+ cur[i].flags & HWC_SKIP_LAYER) {
+ // skip layers handled by the HAL
+ continue;
+ }
+ }
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
@@ -1042,7 +1129,7 @@ void SurfaceFlinger::closeGlobalTransaction()
if (android_atomic_dec(&mTransactionCount) == 1) {
signalEvent();
- // if there is a transaction with a resize, wait for it to
+ // if there is a transaction with a resize, wait for it to
// take effect before returning.
Mutex::Autolock _l(mStateLock);
while (mResizeTransationPending) {
@@ -1086,7 +1173,7 @@ status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
return NO_ERROR;
}
-int SurfaceFlinger::setOrientation(DisplayID dpy,
+int SurfaceFlinger::setOrientation(DisplayID dpy,
int orientation, uint32_t flags)
{
if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
@@ -1119,14 +1206,17 @@ sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
int(w), int(h));
return surfaceHandle;
}
-
+
//LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
sp<Layer> normalLayer;
switch (flags & eFXSurfaceMask) {
case eFXSurfaceNormal:
+#if HAS_PUSH_BUFFERS
if (UNLIKELY(flags & ePushBuffers)) {
layer = createPushBuffersSurface(client, d, w, h, flags);
- } else {
+ } else
+#endif
+ {
normalLayer = createNormalSurface(client, d, w, h, flags, format);
layer = normalLayer;
}
@@ -1145,7 +1235,7 @@ sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
ssize_t token = addClientLayer(client, layer);
surfaceHandle = layer->getSurface();
- if (surfaceHandle != 0) {
+ if (surfaceHandle != 0) {
params->token = token;
params->identity = surfaceHandle->getIdentity();
params->width = w;
@@ -1229,7 +1319,7 @@ status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
/*
* called by the window manager, when a surface should be marked for
* destruction.
- *
+ *
* The surface is removed from the current and drawing lists, but placed
* in the purgatory queue, so it's not destroyed right-away (we need
* to wait for all client's references to go away first).
@@ -1250,7 +1340,7 @@ status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
{
// called by ~ISurface() when all references are gone
-
+
class MessageDestroySurface : public MessageBase {
SurfaceFlinger* flinger;
sp<LayerBaseClient> layer;
@@ -1263,9 +1353,9 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
layer.clear(); // clear it outside of the lock;
Mutex::Autolock _l(flinger->mStateLock);
/*
- * remove the layer from the current list -- chances are that it's
- * not in the list anyway, because it should have been removed
- * already upon request of the client (eg: window manager).
+ * remove the layer from the current list -- chances are that it's
+ * not in the list anyway, because it should have been removed
+ * already upon request of the client (eg: window manager).
* However, a buggy client could have not done that.
* Since we know we don't have any more clients, we don't need
* to use the purgatory.
@@ -1380,7 +1470,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
}
const bool locked(retry >= 0);
if (!locked) {
- snprintf(buffer, SIZE,
+ snprintf(buffer, SIZE,
"SurfaceFlinger appears to be unresponsive, "
"dumping anyways (no locks held)\n");
result.append(buffer);
@@ -1655,12 +1745,15 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
{
int32_t name = NAME_NOT_FOUND;
sp<Layer> layer(mFlinger->getLayer(sur));
- if (layer == 0) return name;
+ if (layer == 0) {
+ return name;
+ }
// if this layer already has a token, just return it
name = layer->getToken();
- if ((name >= 0) && (layer->getClient() == this))
+ if ((name >= 0) && (layer->getClient() == this)) {
return name;
+ }
name = 0;
do {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8ecfc01..8e286e5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -296,6 +296,7 @@ private:
void handlePageFlip();
bool lockPageFlip(const LayerVector& currentLayers);
void unlockPageFlip(const LayerVector& currentLayers);
+ void handleWorkList();
void handleRepaint();
void postFramebuffer();
void composeSurfaces(const Region& dirty);
@@ -370,6 +371,7 @@ private:
Region mInvalidRegion;
Region mWormholeRegion;
bool mVisibleRegionsDirty;
+ bool mHwWorkListDirty;
bool mDeferReleaseConsole;
bool mFreezeDisplay;
int32_t mFreezeCount;