summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2013-03-07 01:47:34 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-03-07 01:47:34 +0000
commit438ca07b6ba74235e87bfbd78c94874d8bbde391 (patch)
tree40fdc15cc3c3547cc39292313aff03ef22c708b0
parent175264b09c6080b29a23fc9f545d4b99445714bd (diff)
parent13127d8921356dff794250e04208c3ed60b3a3df (diff)
downloadframeworks_native-438ca07b6ba74235e87bfbd78c94874d8bbde391.zip
frameworks_native-438ca07b6ba74235e87bfbd78c94874d8bbde391.tar.gz
frameworks_native-438ca07b6ba74235e87bfbd78c94874d8bbde391.tar.bz2
Merge changes I66511c08,Ia051949f,Ic7451365,I5b571a4c into jb-mr2-dev
* changes: Get rid of LayerBase. Make LayerDim a regular Layer instead of a LayerBase fold LayerBaseClient into LayerBase Remove support for ScreenshotLayer
-rw-r--r--include/gui/ISurfaceComposerClient.h2
-rw-r--r--services/surfaceflinger/Android.mk2
-rw-r--r--services/surfaceflinger/Client.cpp13
-rw-r--r--services/surfaceflinger/Client.h10
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp8
-rw-r--r--services/surfaceflinger/DisplayDevice.h8
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp15
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h1
-rw-r--r--services/surfaceflinger/Layer.cpp683
-rw-r--r--services/surfaceflinger/Layer.h311
-rw-r--r--services/surfaceflinger/LayerBase.cpp660
-rw-r--r--services/surfaceflinger/LayerBase.h401
-rw-r--r--services/surfaceflinger/LayerDim.cpp25
-rw-r--r--services/surfaceflinger/LayerDim.h8
-rw-r--r--services/surfaceflinger/LayerScreenshot.cpp47
-rw-r--r--services/surfaceflinger/LayerScreenshot.h41
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp126
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h29
18 files changed, 976 insertions, 1414 deletions
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 @@ public:
eProtectedByDRM = 0x00001000,
eFXSurfaceNormal = 0x00000000,
- eFXSurfaceBlur = 0x00010000, // deprecated, same as Dim
eFXSurfaceDim = 0x00020000,
- eFXSurfaceScreenshot= 0x00030000,
eFXSurfaceMask = 0x000F0000,
};
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 @@ LOCAL_SRC_FILES:= \
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 @@ Client::~Client()
{
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 @@ status_t Client::initCheck() const {
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 @@ void Client::detachLayer(const LayerBaseClient* layer)
}
}
}
-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 @@ namespace android {
// ---------------------------------------------------------------------------
-class LayerBaseClient;
+class Layer;
class SurfaceFlinger;
// ---------------------------------------------------------------------------
@@ -44,11 +44,11 @@ public:
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 @@ private:
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::setViewportAndProjection(const sp<const DisplayDevice>& hw)
// ----------------------------------------------------------------------------
-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 @@ namespace android {
class DisplayInfo;
class FramebufferSurface;
-class LayerBase;
+class Layer;
class SurfaceFlinger;
class HWComposer;
@@ -99,8 +99,8 @@ public:
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 @@ private:
*/
// 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 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
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 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
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 @@ namespace android {
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 @@ namespace android {
// ---------------------------------------------------------------------------
+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 @@ void Layer::onFirstRef()
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,18 +131,83 @@ void Layer::onFrameAvailable() {
// 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()
+String8 Layer::getName() const {
+ return mName;
+}
+
+void Layer::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;
+}
+
+status_t Layer::setBuffers( uint32_t w, uint32_t h,
+ PixelFormat format, uint32_t flags)
{
+ // this surfaces pixel format
+ PixelFormatInfo info;
+ status_t err = getPixelFormatInfo(format, &info);
+ if (err) {
+ ALOGE("unsupported pixelformat %d", format);
+ return err;
+ }
+
+ uint32_t const maxSurfaceDims = min(
+ mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
+
+ // never allow a surface larger than what our underlying GL implementation
+ // can handle.
+ if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
+ ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
+ return BAD_VALUE;
+ }
+
+ mFormat = format;
+
+ mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
+ mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
+ mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
+ mCurrentOpacity = getOpacityForFormat(format);
+
+ mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
+ mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
+ mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
+
+ 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
@@ -159,46 +243,27 @@ sp<ISurface> Layer::createSurface()
return sur;
}
-wp<IBinder> Layer::getSurfaceTextureBinder() const
-{
+wp<IBinder> Layer::getSurfaceTextureBinder() const {
return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
}
-status_t Layer::setBuffers( uint32_t w, uint32_t h,
- PixelFormat format, uint32_t flags)
+sp<ISurface> Layer::getSurface()
{
- // this surfaces pixel format
- PixelFormatInfo info;
- status_t err = getPixelFormatInfo(format, &info);
- if (err) {
- ALOGE("unsupported pixelformat %d", format);
- return err;
- }
+ sp<ISurface> s;
+ Mutex::Autolock _l(mLock);
- uint32_t const maxSurfaceDims = min(
- mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
+ LOG_ALWAYS_FATAL_IF(mHasSurface,
+ "Layer::getSurface() has already been called");
- // never allow a surface larger than what our underlying GL implementation
- // can handle.
- if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
- ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
- return BAD_VALUE;
- }
-
- mFormat = format;
-
- mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
- mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
- mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
- mCurrentOpacity = getOpacityForFormat(format);
-
- mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
- mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
- mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
-
- return NO_ERROR;
+ 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 @@ uint32_t Layer::getContentTransform() const {
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 @@ void Layer::setGeometry(
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 @@ void Layer::setGeometry(
*/
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 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
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 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
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 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
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 @@ bool Layer::getOpacityForFormat(uint32_t format)
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 @@ bool Layer::isProtected() const
(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 @@ uint32_t Layer::doTransaction(uint32_t flags)
(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 @@ uint32_t Layer::doTransaction(uint32_t flags)
}
}
- 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 @@ void Layer::onPostComposition() {
}
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,9 +1145,64 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
return outDirtyRegion;
}
+uint32_t Layer::getEffectiveUsage(uint32_t usage) const
+{
+ // TODO: should we do something special if mSecure is set?
+ if (mProtectedByApp) {
+ // need a hardware-protected path to external video sink
+ usage |= GraphicBuffer::USAGE_PROTECTED;
+ }
+ usage |= GraphicBuffer::USAGE_HW_COMPOSER;
+ return usage;
+}
+
+void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
+ uint32_t orientation = 0;
+ if (!mFlinger->mDebugDisableTransformHint) {
+ // The transform hint is used to improve performance, but we can
+ // only have a single transform hint, it cannot
+ // apply to all displays.
+ const Transform& planeTransform(hw->getTransform());
+ orientation = planeTransform.getOrientation();
+ if (orientation & Transform::ROT_INVALID) {
+ orientation = 0;
+ }
+ }
+ mSurfaceFlingerConsumer->setTransformHint(orientation);
+}
+
+// ----------------------------------------------------------------------------
+// debugging
+// ----------------------------------------------------------------------------
+
void Layer::dump(String8& result, char* buffer, size_t SIZE) const
{
- LayerBaseClient::dump(result, buffer, SIZE);
+ 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;
@@ -728,42 +1226,29 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
}
}
-void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
-{
- LayerBaseClient::dumpStats(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()
-{
- LayerBaseClient::clearStats();
+void Layer::clearStats() {
mFrameTracker.clear();
}
-uint32_t Layer::getEffectiveUsage(uint32_t usage) const
-{
- // TODO: should we do something special if mSecure is set?
- if (mProtectedByApp) {
- // need a hardware-protected path to external video sink
- usage |= GraphicBuffer::USAGE_PROTECTED;
- }
- usage |= GraphicBuffer::USAGE_HW_COMPOSER;
- return usage;
+// ---------------------------------------------------------------------------
+
+Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
+ const sp<Layer>& layer)
+ : mFlinger(flinger), mLayer(layer) {
}
-void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
- uint32_t orientation = 0;
- if (!mFlinger->mDebugDisableTransformHint) {
- // The transform hint is used to improve performance, but we can
- // only have a single transform hint, it cannot
- // apply to all displays.
- const Transform& planeTransform(hw->getTransform());
- orientation = planeTransform.getOrientation();
- if (orientation & Transform::ROT_INVALID) {
- orientation = 0;
- }
- }
- mSurfaceFlingerConsumer->setTransformHint(orientation);
+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 <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.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 <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <private/gui/LayerState.h>
-#include "SurfaceFlingerConsumer.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();
+
+ // 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;
- // LayerBase interface
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;
+
+ /*
+ * called with the state lock when the surface is removed from the
+ * current list
+ */
+ virtual void onRemoved();
- // only for debugging
- inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
+
+ 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 @@ private:
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 @@ namespace android {
// ---------------------------------------------------------------------------
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 @@ void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) con
}
}
+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 @@ public:
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..f1e9c65 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 @@ bool SurfaceFlinger::authenticateSurfaceTexture(
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 @@ bool SurfaceFlinger::authenticateSurfaceTexture(
// 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 @@ void SurfaceFlinger::rebuildLayerStacks() {
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 @@ void SurfaceFlinger::rebuildLayerStacks() {
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 @@ void SurfaceFlinger::setUpHWComposer() {
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 @@ void SurfaceFlinger::setUpHWComposer() {
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 @@ void SurfaceFlinger::setUpHWComposer() {
* 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 @@ void SurfaceFlinger::postFramebuffer()
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 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
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 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
// 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 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
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 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
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 @@ void SurfaceFlinger::computeVisibleRegions(
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 @@ void SurfaceFlinger::handlePageFlip()
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 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
* 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 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
} 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::drawWormhole(const sp<const DisplayDevice>& hw,
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 @@ void SurfaceFlinger::addClientLayer(const sp<Client>& client,
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 @@ status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
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 @@ status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
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 @@ uint32_t SurfaceFlinger::setClientStateLocked(
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 @@ sp<ISurface> SurfaceFlinger::createLayer(
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 @@ sp<ISurface> SurfaceFlinger::createLayer(
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 @@ sp<LayerDim> SurfaceFlinger::createDimLayer(
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 SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBind
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 @@ status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBind
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 @@ void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& inde
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 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
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 @@ void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& inde
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 @@ void SurfaceFlinger::dumpAllLocked(
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 @@ void SurfaceFlinger::dumpAllLocked(
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 @@ void SurfaceFlinger::dumpAllLocked(
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 @@ status_t SurfaceFlinger::captureScreenImplLocked(
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);
@@ -2896,15 +2876,15 @@ SurfaceFlinger::LayerVector::LayerVector() {
}
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 DisplayEventConnection;
class EventThread;
class IGraphicBufferAlloc;
class Layer;
-class LayerBase;
-class LayerBaseClient;
class LayerDim;
-class LayerScreenshot;
class Surface;
// ---------------------------------------------------------------------------
@@ -125,15 +122,12 @@ public:
// 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 @@ private:
* 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 @@ private:
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 @@ private:
// 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 @@ private:
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 @@ private:
// protected by mDestroyedLayerLock;
mutable Mutex mDestroyedLayerLock;
- Vector<LayerBase const *> mDestroyedLayers;
+ Vector<Layer const *> mDestroyedLayers;
/* ------------------------------------------------------------------------
* Feature prototyping