diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
commit | b798689749c64baba81f02e10cf2157c747d6b46 (patch) | |
tree | da394a395ddb1a6cf69193314846b03fe47a397e /libs/surfaceflinger | |
parent | f013e1afd1e68af5e3b868c26a653bbfb39538f8 (diff) | |
download | frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.zip frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.gz frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.bz2 |
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'libs/surfaceflinger')
-rw-r--r-- | libs/surfaceflinger/BootAnimation.cpp | 4 | ||||
-rw-r--r-- | libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 4 | ||||
-rw-r--r-- | libs/surfaceflinger/DisplayHardware/DisplayHardware.h | 6 | ||||
-rw-r--r-- | libs/surfaceflinger/Layer.cpp | 4 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.cpp | 17 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.h | 79 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBlur.cpp | 2 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBuffer.cpp | 617 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBuffer.h | 134 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerScreenshot.cpp | 2 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 24 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.h | 14 | ||||
-rw-r--r-- | libs/surfaceflinger/Transform.h | 2 |
13 files changed, 596 insertions, 313 deletions
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp index e9e34c3..d18f59a 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -36,8 +36,8 @@ #include <ui/ISurfaceFlingerClient.h> #include <ui/EGLNativeWindowSurface.h> -#include <graphics/SkBitmap.h> -#include <graphics/SkImageDecoder.h> +#include <core/SkBitmap.h> +#include <images/SkImageDecoder.h> #include <GLES/egl.h> diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index cd72179..19e32ec 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -250,7 +250,7 @@ void DisplayHardware::init(uint32_t dpy) mOverlayEngine = NULL; if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) { - overlay_open(module, &mOverlayEngine); + overlay_control_open(module, &mOverlayEngine); } } @@ -266,7 +266,7 @@ void DisplayHardware::fini() eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(mDisplay); copybit_close(mBlitEngine); - overlay_close(mOverlayEngine); + overlay_control_close(mOverlayEngine); } void DisplayHardware::releaseScreen() const diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index de4a2cc..df97b60 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -26,7 +26,7 @@ #include "DisplayHardware/DisplayHardwareBase.h" -struct overlay_device_t; +struct overlay_control_device_t; struct copybit_device_t; struct copybit_image_t; struct copybit_t; @@ -78,7 +78,7 @@ public: void getDisplaySurface(GGLSurface* fb) const; EGLDisplay getEGLDisplay() const { return mDisplay; } copybit_device_t* getBlitEngine() const { return mBlitEngine; } - overlay_device_t* getOverlayEngine() const { return mOverlayEngine; } + overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; } Rect bounds() const { return Rect(mWidth, mHeight); @@ -103,7 +103,7 @@ private: mutable Region mDirty; sp<EGLDisplaySurface> mDisplaySurface; copybit_device_t* mBlitEngine; - overlay_device_t* mOverlayEngine; + overlay_control_device_t* mOverlayEngine; }; }; // namespace android diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 8ba0851..f65d669 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -316,7 +316,7 @@ uint32_t Layer::doTransaction(uint32_t flags) if (err == NO_ERROR) { const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0; android_atomic_and(~mask, &(lcblk->swapState)); - // since a buffer became availlable, we can let the client go... + // since a buffer became available, we can let the client go... mFlinger->scheduleBroadcast(client); mResizeTransactionDone = true; @@ -511,7 +511,7 @@ Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions) } mResizeTransactionDone = false; recomputeVisibleRegions = true; - invalidate = true; + this->contentDirty = true; } } diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index af353e2..bdefba3 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -53,14 +53,15 @@ Vector<GLuint> LayerBase::deletedTextures; int32_t LayerBase::sIdentity = 0; LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) - : dpy(display), invalidate(false), + : dpy(display), contentDirty(false), mFlinger(flinger), mTransformed(false), mOrientation(0), mCanUseCopyBit(false), mTransactionFlags(0), mPremultipliedAlpha(true), - mIdentity(uint32_t(android_atomic_inc(&sIdentity))) + mIdentity(uint32_t(android_atomic_inc(&sIdentity))), + mInvalidate(0) { const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware()); mFlags = hw.getFlags(); @@ -205,7 +206,7 @@ uint32_t LayerBase::doTransaction(uint32_t flags) if (temp.sequence != front.sequence) { // invalidate and recompute the visible regions if needed flags |= eVisibleRegion; - this->invalidate = true; + this->contentDirty = true; } // Commit the transaction @@ -299,12 +300,22 @@ void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) void LayerBase::unlockPageFlip( const Transform& planeTransform, Region& outDirtyRegion) { + if ((android_atomic_and(~1, &mInvalidate)&1) == 1) { + outDirtyRegion.orSelf(visibleRegionScreen); + } } void LayerBase::finishPageFlip() { } +void LayerBase::invalidate() +{ + if ((android_atomic_or(1, &mInvalidate)&1) == 0) { + mFlinger->signalEvent(); + } +} + void LayerBase::drawRegion(const Region& reg) const { Region::iterator iterator(reg); diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index b3f3771..5e14dc85 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -75,7 +75,7 @@ public: virtual ~LayerBase(); DisplayID dpy; - mutable bool invalidate; + mutable bool contentDirty; Region visibleRegionScreen; Region transparentRegionScreen; Region coveredRegionScreen; @@ -112,18 +112,87 @@ public: Rect visibleBounds() const; void drawRegion(const Region& reg) const; + void invalidate(); + + /** + * 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 Region& clip) const; + + /** + * onDraw - draws the surface. + */ virtual void onDraw(const Region& clip) const = 0; + + /** + * initStates - called just after construction + */ virtual void initStates(uint32_t w, uint32_t h, uint32_t flags); + + /** + * setSizeChanged - called when the *current* state's size is changed. + */ virtual void setSizeChanged(uint32_t w, uint32_t h); + + /** + * 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 correspond to any area of the surface that is covered + * (transparently or not) by another surface. + */ virtual void setCoveredRegion(const Region& coveredRegion); + + /** + * getPhysicalSize - returns the physical size of the drawing state of + * the surface. If the surface is backed by a bitmap, this is the size of + * the bitmap (as opposed to the size of the drawing state). + */ virtual Point getPhysicalSize() const; + + /** + * lockPageFlip - 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 void lockPageFlip(bool& recomputeVisibleRegions); + + /** + * unlockPageFlip - called each time the screen is redrawn. updates the + * final dirty region wrt the planeTransform. + * At this point, all visible regions, surface position and size, etc... are + * correct. + */ virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); + + /** + * finishPageFlip - called after all surfaces have drawn. + */ virtual void finishPageFlip(); + + /** + * needsBlending - true if this surface needs blending + */ virtual bool needsBlending() const { return false; } + + /** + * isSecure - true if this surface is secure, that is if it prevents a + * screenshot to be taken, + */ virtual bool isSecure() const { return false; } enum { // flags for doTransaction() @@ -162,7 +231,6 @@ protected: bool canUseCopybit() const; - SurfaceFlinger* mFlinger; uint32_t mFlags; @@ -184,7 +252,10 @@ protected: bool mPremultipliedAlpha; // only read - const uint32_t mIdentity; + const uint32_t mIdentity; + + // atomic + volatile int32_t mInvalidate; private: @@ -254,7 +325,7 @@ public: { return INVALID_OPERATION; } virtual void postBuffer(ssize_t offset) { } virtual void unregisterBuffers() { }; - virtual sp<Overlay> createOverlay( + virtual sp<OverlayRef> createOverlay( uint32_t w, uint32_t h, int32_t format) { return NULL; }; diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index e3ae7fb..efadbcf 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -71,7 +71,7 @@ uint32_t LayerBlur::doTransaction(uint32_t flags) mRefreshCache = true; mCacheDirty = true; flags |= eVisibleRegion; - this->invalidate = true; + this->contentDirty = true; } return LayerBase::doTransaction(flags); } diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 3861e68..700e4f5 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -46,7 +46,7 @@ const char* const LayerBuffer::typeID = "LayerBuffer"; LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, Client* client, int32_t i) : LayerBaseClient(flinger, display, client, i), - mBuffer(0), mTextureName(-1U), mInvalidate(false), mNeedsBlending(false) + mNeedsBlending(false) { } @@ -57,43 +57,333 @@ LayerBuffer::~LayerBuffer() s->disown(); mClientSurface.clear(); } +} - // this should always be called from the OpenGL thread - if (mTextureName != -1U) { - //glDeleteTextures(1, &mTextureName); - deletedTextures.add(mTextureName); - } - // to help debugging we set those to zero - mWidth = mHeight = 0; +sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const +{ + Mutex::Autolock _l(mLock); + return mClientSurface.promote(); } -bool LayerBuffer::needsBlending() const +sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const { + sp<SurfaceBuffer> s; Mutex::Autolock _l(mLock); + s = mClientSurface.promote(); + if (s == 0) { + s = new SurfaceBuffer(clientIndex(), + const_cast<LayerBuffer *>(this)); + mClientSurface = s; + } + return s; +} + +bool LayerBuffer::needsBlending() const { return mNeedsBlending; } +void LayerBuffer::setNeedsBlending(bool blending) { + mNeedsBlending = blending; +} + +void LayerBuffer::postBuffer(ssize_t offset) +{ + sp<Source> source(getSource()); + if (source != 0) + source->postBuffer(offset); +} + +void LayerBuffer::unregisterBuffers() +{ + sp<Source> source(getSource()); + if (source != 0) + source->unregisterBuffers(); + // XXX: clear mSource +} + +uint32_t LayerBuffer::doTransaction(uint32_t flags) +{ + sp<Source> source(getSource()); + if (source != 0) + source->onTransaction(flags); + return LayerBase::doTransaction(flags); +} + +void LayerBuffer::unlockPageFlip(const Transform& planeTransform, + Region& outDirtyRegion) +{ + // this code-path must be as tight as possible, it's called each time + // the screen is composited. + sp<Source> source(getSource()); + if (source != 0) + source->onVisibilityResolved(planeTransform); + LayerBase::unlockPageFlip(planeTransform, outDirtyRegion); +} + void LayerBuffer::onDraw(const Region& clip) const { + sp<Source> source(getSource()); + if (LIKELY(source != 0)) { + source->onDraw(clip); + } else { + clearWithOpenGL(clip); + } +} + +/** + * This creates a "buffer" source for this surface + */ +status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride, + PixelFormat format, const sp<IMemoryHeap>& memoryHeap) +{ + Mutex::Autolock _l(mLock); + if (mSource != 0) + return INVALID_OPERATION; + + sp<BufferSource> source = new BufferSource(*this, w, h, + hstride, vstride, format, memoryHeap); + + status_t result = source->getStatus(); + if (result == NO_ERROR) { + mSource = source; + } + return result; +} + +/** + * This creates an "overlay" source for this surface + */ +sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f) +{ + sp<OverlayRef> result; + Mutex::Autolock _l(mLock); + if (mSource != 0) + return result; + + sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f); + if (result != 0) { + mSource = source; + } + return result; +} + +sp<LayerBuffer::Source> LayerBuffer::getSource() const { + Mutex::Autolock _l(mLock); + return mSource; +} + +// ============================================================================ +// LayerBuffer::SurfaceBuffer +// ============================================================================ + +LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner) +: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner) +{ +} + +LayerBuffer::SurfaceBuffer::~SurfaceBuffer() +{ + unregisterBuffers(); + mOwner = 0; +} + +status_t LayerBuffer::SurfaceBuffer::registerBuffers( + int w, int h, int hs, int vs, + PixelFormat format, const sp<IMemoryHeap>& heap) +{ + LayerBuffer* owner(getOwner()); + if (owner) + return owner->registerBuffers(w, h, hs, vs, format, heap); + return NO_INIT; +} + +void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset) +{ + LayerBuffer* owner(getOwner()); + if (owner) + owner->postBuffer(offset); +} + +void LayerBuffer::SurfaceBuffer::unregisterBuffers() +{ + LayerBuffer* owner(getOwner()); + if (owner) + owner->unregisterBuffers(); +} + +sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay( + uint32_t w, uint32_t h, int32_t format) { + sp<OverlayRef> result; + LayerBuffer* owner(getOwner()); + if (owner) + result = owner->createOverlay(w, h, format); + return result; +} + +void LayerBuffer::SurfaceBuffer::disown() +{ + Mutex::Autolock _l(mLock); + mOwner = 0; +} + +// ============================================================================ +// LayerBuffer::Buffer +// ============================================================================ + +LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset, + int w, int h, int hs, int vs, int f) +: mHeap(heap) +{ + NativeBuffer& src(mNativeBuffer); + src.crop.l = 0; + src.crop.t = 0; + src.crop.r = w; + src.crop.b = h; + src.img.w = hs ?: w; + src.img.h = vs ?: h; + src.img.format = f; + src.img.offset = offset; + src.img.base = heap->base(); + src.img.fd = heap->heapID(); + // FIXME: make sure this buffer lies within the heap, in which case, set + // mHeap to null +} + +LayerBuffer::Buffer::~Buffer() +{ +} + +// ============================================================================ +// LayerBuffer::Source +// LayerBuffer::BufferSource +// LayerBuffer::OverlaySource +// ============================================================================ + +LayerBuffer::Source::Source(LayerBuffer& layer) + : mLayer(layer) +{ +} +LayerBuffer::Source::~Source() { +} +void LayerBuffer::Source::onDraw(const Region& clip) const { +} +void LayerBuffer::Source::onTransaction(uint32_t flags) { +} +void LayerBuffer::Source::onVisibilityResolved( + const Transform& planeTransform) { +} +void LayerBuffer::Source::postBuffer(ssize_t offset) { +} +void LayerBuffer::Source::unregisterBuffers() { +} + +// --------------------------------------------------------------------------- + +LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer, + int w, int h, int hstride, int vstride, + PixelFormat format, const sp<IMemoryHeap>& memoryHeap) + : Source(layer), mStatus(NO_ERROR), mTextureName(-1U) +{ + if (memoryHeap == NULL) { + // this is allowed, but in this case, it is illegal to receive + // postBuffer(). The surface just erases the framebuffer with + // fully transparent pixels. + mHeap.clear(); + mWidth = w; + mHeight = h; + mLayer.setNeedsBlending(false); + return; + } + + status_t err = (memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT; + if (err != NO_ERROR) { + mStatus = err; + return; + } + + // TODO: validate format/parameters + mHeap = memoryHeap; + mWidth = w; + mHeight = h; + mHStride = hstride; + mVStride = vstride; + mFormat = format; + PixelFormatInfo info; + getPixelFormatInfo(format, &info); + mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0); +} + +LayerBuffer::BufferSource::~BufferSource() +{ + if (mTextureName != -1U) { + LayerBase::deletedTextures.add(mTextureName); + } +} + +void LayerBuffer::BufferSource::postBuffer(ssize_t offset) +{ + sp<IMemoryHeap> heap; + int w, h, hs, vs, f; + { // scope for the lock + Mutex::Autolock _l(mLock); + w = mWidth; + h = mHeight; + hs= mHStride; + vs= mVStride; + f = mFormat; + heap = mHeap; + } + + sp<Buffer> buffer; + if (heap != 0) { + buffer = new LayerBuffer::Buffer(heap, offset, w, h, hs, vs, f); + if (buffer->getStatus() != NO_ERROR) + buffer.clear(); + setBuffer(buffer); + mLayer.invalidate(); + } +} + +void LayerBuffer::BufferSource::unregisterBuffers() +{ + Mutex::Autolock _l(mLock); + mHeap.clear(); + mBuffer.clear(); + mLayer.invalidate(); +} + +sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const +{ + Mutex::Autolock _l(mLock); + return mBuffer; +} + +void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer) +{ + Mutex::Autolock _l(mLock); + mBuffer = buffer; +} + +void LayerBuffer::BufferSource::onDraw(const Region& clip) const +{ sp<Buffer> buffer(getBuffer()); if (UNLIKELY(buffer == 0)) { // nothing to do, we don't have a buffer - clearWithOpenGL(clip); + mLayer.clearWithOpenGL(clip); return; } status_t err = NO_ERROR; NativeBuffer src(buffer->getBuffer()); - const int can_use_copybit = canUseCopybit(); + const Rect& transformedBounds = mLayer.getTransformedBounds(); + const int can_use_copybit = mLayer.canUseCopybit(); if (can_use_copybit) { - //StopWatch watch("MDP"); - const int src_width = src.crop.r - src.crop.l; const int src_height = src.crop.b - src.crop.t; - int W = mTransformedBounds.width(); - int H = mTransformedBounds.height(); - if (getOrientation() & Transform::ROT_90) { + int W = transformedBounds.width(); + int H = transformedBounds.height(); + if (mLayer.getOrientation() & Transform::ROT_90) { int t(W); W=H; H=t; } @@ -104,7 +394,7 @@ void LayerBuffer::onDraw(const Region& clip) const * the requested scale factor, in which case we perform the scaling * in several passes. */ - copybit_device_t* copybit = mFlinger->getBlitEngine(); + copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine(); const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT); const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT); @@ -117,13 +407,10 @@ void LayerBuffer::onDraw(const Region& clip) const else if (src_height*mag < H) yscale = mag; if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) { - //LOGD("MDP scaling hack w=%d, h=%d, ww=%d, wh=%d, xs=%f, ys=%f", - // src_width, src_height, W, H, xscale, yscale); - if (UNLIKELY(mTemporaryDealer == 0)) { // allocate a memory-dealer for this the first time - mTemporaryDealer = mFlinger->getSurfaceHeapManager() - ->createHeap(ISurfaceComposer::eHardware); + mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager() + ->createHeap(ISurfaceComposer::eHardware); mTempBitmap.init(mTemporaryDealer); } @@ -149,14 +436,14 @@ void LayerBuffer::onDraw(const Region& clip) const } } - const DisplayHardware& hw(graphicPlane(0).displayHardware()); + const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware()); copybit_image_t dst; hw.getDisplaySurface(&dst); const copybit_rect_t& drect - = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds); - const State& s(drawingState()); + = reinterpret_cast<const copybit_rect_t&>(transformedBounds); + const State& s(mLayer.drawingState()); region_iterator it(clip); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation()); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, mLayer.getOrientation()); copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha); copybit->set_parameter(copybit, COPYBIT_DITHER, s.flags & ISurfaceComposer::eLayerDither ? @@ -167,245 +454,115 @@ void LayerBuffer::onDraw(const Region& clip) const if (!can_use_copybit || err) { if (UNLIKELY(mTextureName == -1LU)) { - mTextureName = createTexture(); + mTextureName = mLayer.createTexture(); } GLuint w = 0; GLuint h = 0; GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.crop.r; - t.height = src.crop.b; - t.stride = src.img.w; - t.vstride= src.img.h; - t.format = src.img.format; - t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); + t.version = sizeof(GGLSurface); + t.width = src.crop.r; + t.height = src.crop.b; + t.stride = src.img.w; + t.vstride= src.img.h; + t.format = src.img.format; + t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureName, t, w, h); - drawWithOpenGL(clip, mTextureName, t); + mLayer.loadTexture(dirty, mTextureName, t, w, h); + mLayer.drawWithOpenGL(clip, mTextureName, t); } } -void LayerBuffer::invalidateLocked() -{ - mInvalidate = true; - mFlinger->signalEvent(); -} - -void LayerBuffer::invalidate() -{ - Mutex::Autolock _l(mLock); - invalidateLocked(); -} - -void LayerBuffer::unlockPageFlip(const Transform& planeTransform, - Region& outDirtyRegion) -{ - Mutex::Autolock _l(mLock); - if (mInvalidate) { - mInvalidate = false; - outDirtyRegion.orSelf(visibleRegionScreen); - } -} - -sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const -{ - Mutex::Autolock _l(mLock); - return mClientSurface.promote(); -} - -sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const -{ - sp<SurfaceBuffer> s; - Mutex::Autolock _l(mLock); - s = mClientSurface.promote(); - if (s == 0) { - s = new SurfaceBuffer(clientIndex(), - const_cast<LayerBuffer *>(this)); - mClientSurface = s; - } - return s; -} - - -status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride, - PixelFormat format, const sp<IMemoryHeap>& memoryHeap) -{ - if (memoryHeap == NULL) { - // this is allowed, but in this case, it is illegal to receive - // postBuffer(). The surface just erases the framebuffer with - // fully transparent pixels. - mHeap.clear(); - mWidth = w; - mHeight = h; - mNeedsBlending = false; - return NO_ERROR; - } - - status_t err = (memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT; - if (err != NO_ERROR) - return err; - - // TODO: validate format/parameters - - Mutex::Autolock _l(mLock); - mHeap = memoryHeap; - mWidth = w; - mHeight = h; - mHStride = hstride; - mVStride = vstride; - mFormat = format; - PixelFormatInfo info; - getPixelFormatInfo(format, &info); - mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; - return NO_ERROR; -} - -void LayerBuffer::postBuffer(ssize_t offset) -{ - sp<IMemoryHeap> heap; - int w, h, hs, vs, f; - { // scope for the lock - Mutex::Autolock _l(mLock); - w = mWidth; - h = mHeight; - hs= mHStride; - vs= mVStride; - f = mFormat; - heap = mHeap; - } - - sp<Buffer> buffer; - if (heap != 0) { - buffer = new Buffer(heap, offset, w, h, hs, vs, f); - if (buffer->getStatus() != NO_ERROR) - buffer.clear(); - setBuffer(buffer); - invalidate(); - } -} +// --------------------------------------------------------------------------- -void LayerBuffer::unregisterBuffers() +LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer, + sp<OverlayRef>* overlayRef, + uint32_t w, uint32_t h, int32_t format) + : Source(layer), mVisibilityChanged(false), mOverlay(0), mOverlayHandle(0) { - Mutex::Autolock _l(mLock); - mHeap.clear(); - mBuffer.clear(); - invalidateLocked(); -} + overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine(); -sp<Overlay> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t format) -{ - sp<Overlay> result; - Mutex::Autolock _l(mLock); - if (mHeap != 0 || mBuffer != 0) { - // we're a push surface. error. - return result; - } - - overlay_device_t* overlay_dev = mFlinger->getOverlayEngine(); if (overlay_dev == NULL) { // overlays not supported - return result; + return; } overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format); if (overlay == NULL) { // couldn't create the overlay (no memory? no more overlays?) - return result; + return; } - - /* TODO: implement the real stuff here */ - - return result; -} - -sp<LayerBuffer::Buffer> LayerBuffer::getBuffer() const -{ - Mutex::Autolock _l(mLock); - return mBuffer; -} -void LayerBuffer::setBuffer(const sp<LayerBuffer::Buffer>& buffer) -{ - Mutex::Autolock _l(mLock); - mBuffer = buffer; -} + // enable dithering... + overlay_dev->setParameter(overlay_dev, overlay, + OVERLAY_DITHER, OVERLAY_ENABLE); -// --------------------------------------------------------------------------- + mOverlay = overlay; + mWidth = overlay->w; + mHeight = overlay->h; + mFormat = overlay->format; + mWidthStride = overlay->w_stride; + mHeightStride = overlay->h_stride; -LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner) - : LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner) -{ -} + mOverlayHandle = overlay->getHandleRef(overlay); + + // NOTE: here it's okay to acquire a reference to "this"m as long as + // the reference is not released before we leave the ctor. + sp<OverlayChanel> chanel = new OverlayChanel(this); -LayerBuffer::SurfaceBuffer::~SurfaceBuffer() -{ - unregisterBuffers(); - mOwner = 0; + *overlayRef = new OverlayRef(mOverlayHandle, chanel, + mWidth, mHeight, mFormat, mWidthStride, mHeightStride); } -status_t LayerBuffer::SurfaceBuffer::registerBuffers( - int w, int h, int hs, int vs, - PixelFormat format, const sp<IMemoryHeap>& heap) -{ - LayerBuffer* owner(getOwner()); - if (owner) - return owner->registerBuffers(w, h, hs, vs, format, heap); - return NO_INIT; +LayerBuffer::OverlaySource::~OverlaySource() +{ } -void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset) +void LayerBuffer::OverlaySource::onTransaction(uint32_t flags) { - LayerBuffer* owner(getOwner()); - if (owner) - owner->postBuffer(offset); + const Layer::State& front(mLayer.drawingState()); + const Layer::State& temp(mLayer.currentState()); + if (temp.sequence != front.sequence) { + mVisibilityChanged = true; + } } -void LayerBuffer::SurfaceBuffer::unregisterBuffers() +void LayerBuffer::OverlaySource::onVisibilityResolved( + const Transform& planeTransform) { - LayerBuffer* owner(getOwner()); - if (owner) - owner->unregisterBuffers(); -} - -sp<Overlay> LayerBuffer::SurfaceBuffer::createOverlay( - uint32_t w, uint32_t h, int32_t format) { - sp<Overlay> result; - LayerBuffer* owner(getOwner()); - if (owner) - result = owner->createOverlay(w, h, format); - return result; + // this code-path must be as tight as possible, it's called each time + // the screen is composited. + if (UNLIKELY(mOverlay != 0)) { + if (mVisibilityChanged) { + mVisibilityChanged = false; + const Rect& bounds = mLayer.getTransformedBounds(); + int x = bounds.left; + int y = bounds.top; + int w = bounds.width(); + int h = bounds.height(); + + // we need a lock here to protect "destroy" + Mutex::Autolock _l(mLock); + if (mOverlay) { + overlay_control_device_t* overlay_dev = + mLayer.mFlinger->getOverlayEngine(); + overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h); + overlay_dev->setParameter(overlay_dev, mOverlay, + OVERLAY_TRANSFORM, mLayer.getOrientation()); + } + } + } } -void LayerBuffer::SurfaceBuffer::disown() +void LayerBuffer::OverlaySource::serverDestroy() { + // we need a lock here to protect "onVisibilityResolved" Mutex::Autolock _l(mLock); - mOwner = 0; -} - - -// --------------------------------------------------------------------------- - -LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset, - int w, int h, int hs, int vs, int f) - : mCount(0), mHeap(heap) -{ - NativeBuffer& src(mNativeBuffer); - src.crop.l = 0; - src.crop.t = 0; - src.crop.r = w; - src.crop.b = h; - src.img.w = hs ?: w; - src.img.h = vs ?: h; - src.img.format = f; - src.img.offset = offset; - src.img.base = heap->base(); - src.img.fd = heap->heapID(); - // FIXME: make sure this buffer lies within the heap, in which case, set - // mHeap to null -} - -LayerBuffer::Buffer::~Buffer() -{ + if (mOverlay) { + overlay_control_device_t* overlay_dev = + mLayer.mFlinger->getOverlayEngine(); + overlay_dev->destroyOverlay(overlay_dev, mOverlay); + mOverlay = 0; + } } // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 3e616f2..63ec2cf 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -33,10 +33,24 @@ namespace android { class MemoryDealer; class Region; -class Overlay; +class OverlayRef; class LayerBuffer : public LayerBaseClient { + class Source : public LightRefBase<Source> { + public: + Source(LayerBuffer& layer); + virtual ~Source(); + virtual void onDraw(const Region& clip) const; + virtual void onTransaction(uint32_t flags); + virtual void onVisibilityResolved(const Transform& planeTransform); + virtual void postBuffer(ssize_t offset); + virtual void unregisterBuffers(); + protected: + LayerBuffer& mLayer; + }; + + public: static const uint32_t typeInfo; static const char* const typeID; @@ -51,39 +65,31 @@ public: virtual sp<LayerBaseClient::Surface> getSurface() const; virtual void onDraw(const Region& clip) const; + virtual uint32_t doTransaction(uint32_t flags); virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion); status_t registerBuffers(int w, int h, int hstride, int vstride, PixelFormat format, const sp<IMemoryHeap>& heap); void postBuffer(ssize_t offset); void unregisterBuffers(); - sp<Overlay> createOverlay(uint32_t w, uint32_t h, int32_t format); - void invalidate(); - void invalidateLocked(); + sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format); + + sp<Source> getSource() const; + void setNeedsBlending(bool blending); + const Rect& getTransformedBounds() const { + return mTransformedBounds; + } private: - - struct NativeBuffer - { + struct NativeBuffer { copybit_image_t img; copybit_rect_t crop; }; - class Buffer - { + class Buffer : public LightRefBase<Buffer> { public: Buffer(const sp<IMemoryHeap>& heap, ssize_t offset, int w, int h, int hs, int vs, int f); - inline void incStrong(void*) const { - android_atomic_inc(&mCount); - } - inline void decStrong(void*) const { - int32_t c = android_atomic_dec(&mCount); - //LOGE_IF(c<1, "Buffer::decStrong() called too many times"); - if (c == 1) { - delete this; - } - } inline status_t getStatus() const { return mHeap!=0 ? NO_ERROR : NO_INIT; } @@ -91,15 +97,87 @@ private: return mNativeBuffer; } protected: + friend class LightRefBase<Buffer>; Buffer& operator = (const Buffer& rhs); Buffer(const Buffer& rhs); ~Buffer(); - mutable volatile int32_t mCount; private: sp<IMemoryHeap> mHeap; NativeBuffer mNativeBuffer; }; + class BufferSource : public Source { + public: + BufferSource(LayerBuffer& layer, + int w, int h, int hstride, int vstride, + PixelFormat format, const sp<IMemoryHeap>& heap); + virtual ~BufferSource(); + + status_t getStatus() const { return mStatus; } + sp<Buffer> getBuffer() const; + void setBuffer(const sp<Buffer>& buffer); + + virtual void onDraw(const Region& clip) const; + virtual void postBuffer(ssize_t offset); + virtual void unregisterBuffers(); + private: + mutable Mutex mLock; + sp<IMemoryHeap> mHeap; + sp<Buffer> mBuffer; + status_t mStatus; + int mWidth; + int mHeight; + int mHStride; + int mVStride; + int mFormat; + mutable sp<MemoryDealer> mTemporaryDealer; + mutable LayerBitmap mTempBitmap; + mutable GLuint mTextureName; + }; + + class OverlaySource : public Source { + public: + OverlaySource(LayerBuffer& layer, + sp<OverlayRef>* overlayRef, + uint32_t w, uint32_t h, int32_t format); + virtual ~OverlaySource(); + virtual void onTransaction(uint32_t flags); + virtual void onVisibilityResolved(const Transform& planeTransform); + private: + void serverDestroy(); + class OverlayChanel : public BnOverlay { + mutable Mutex mLock; + sp<OverlaySource> mSource; + virtual void destroy() { + sp<OverlaySource> source; + { // scope for the lock; + Mutex::Autolock _l(mLock); + source = mSource; + mSource.clear(); + } + if (source != 0) { + source->serverDestroy(); + } + } + public: + OverlayChanel(const sp<OverlaySource>& source) + : mSource(source) { + } + }; + friend class OverlayChanel; + bool mVisibilityChanged; + + overlay_t* mOverlay; + overlay_handle_t const *mOverlayHandle; + uint32_t mWidth; + uint32_t mHeight; + int32_t mFormat; + int32_t mWidthStride; + int32_t mHeightStride; + mutable Mutex mLock; + }; + + class SurfaceBuffer : public LayerBaseClient::Surface { public: @@ -109,7 +187,7 @@ private: PixelFormat format, const sp<IMemoryHeap>& heap); virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); - virtual sp<Overlay> createOverlay( + virtual sp<OverlayRef> createOverlay( uint32_t w, uint32_t h, int32_t format); void disown(); private: @@ -122,24 +200,14 @@ private: }; friend class SurfaceFlinger; - sp<Buffer> getBuffer() const; - void setBuffer(const sp<Buffer>& buffer); sp<SurfaceBuffer> getClientSurface() const; mutable Mutex mLock; - sp<IMemoryHeap> mHeap; - sp<Buffer> mBuffer; - int mWidth; - int mHeight; - int mHStride; - int mVStride; - int mFormat; - mutable GLuint mTextureName; + sp<Source> mSource; + bool mInvalidate; bool mNeedsBlending; mutable wp<SurfaceBuffer> mClientSurface; - mutable sp<MemoryDealer> mTemporaryDealer; - mutable LayerBitmap mTempBitmap; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerScreenshot.cpp b/libs/surfaceflinger/LayerScreenshot.cpp index 9b82bad..3e7132b 100644 --- a/libs/surfaceflinger/LayerScreenshot.cpp +++ b/libs/surfaceflinger/LayerScreenshot.cpp @@ -23,7 +23,7 @@ #include <utils/Errors.h> #include <utils/Log.h> -#include <graphics/SkBitmap.h> +#include <core/SkBitmap.h> #include <ui/EGLDisplaySurface.h> diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index e8de21a..4c719e8 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -231,7 +231,7 @@ copybit_device_t* SurfaceFlinger::getBlitEngine() const return graphicPlane(0).displayHardware().getBlitEngine(); } -overlay_device_t* SurfaceFlinger::getOverlayEngine() const +overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const { return graphicPlane(0).displayHardware().getOverlayEngine(); } @@ -773,12 +773,12 @@ void SurfaceFlinger::computeVisibleRegions( coveredRegion.andSelf(aboveCoveredLayers); // compute this layer's dirty region - if (layer->invalidate) { + if (layer->contentDirty) { // we need to invalidate the whole region dirty = visibleRegion; // as well, as the old visible region dirty.orSelf(layer->visibleRegionScreen); - layer->invalidate = false; + layer->contentDirty = false; } else { // compute the exposed region // dirty = what's visible now - what's wasn't covered before @@ -1456,7 +1456,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", layer->getTypeID(), layer, s.z, layer->tx(), layer->ty(), s.w, s.h, - layer->needsBlending(), layer->invalidate, + layer->needsBlending(), layer->contentDirty, s.alpha, s.flags, s.transform[0], s.transform[1], s.transform[2], s.transform[3]); @@ -1474,22 +1474,6 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) } result.append(buffer); buffer[0] = 0; - /*** LayerBuffer ***/ - LayerBuffer* const lbuf = - LayerBase::dynamicCast<LayerBuffer*>((LayerBase*)layer); - if (lbuf) { - sp<LayerBuffer::Buffer> lbb(lbuf->getBuffer()); - if (lbb != 0) { - const LayerBuffer::NativeBuffer& nbuf(lbb->getBuffer()); - snprintf(buffer, SIZE, - " " - "mBuffer={w=%u, h=%u, f=%d, offset=%u, base=%p, fd=%d }\n", - nbuf.img.w, nbuf.img.h, nbuf.img.format, nbuf.img.offset, - nbuf.img.base, nbuf.img.fd); - } - } - result.append(buffer); - buffer[0] = 0; /*** Layer ***/ Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer); if (l) { diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 92021d0..a242f1a 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -180,7 +180,7 @@ public: } copybit_device_t* getBlitEngine() const; - overlay_device_t* getOverlayEngine() const; + overlay_control_device_t* getOverlayEngine() const; private: friend class BClient; @@ -382,24 +382,16 @@ private: // --------------------------------------------------------------------------- -class FreezeLock { +class FreezeLock : public LightRefBase<FreezeLock> { SurfaceFlinger* mFlinger; - mutable volatile int32_t mCount; public: FreezeLock(SurfaceFlinger* flinger) - : mFlinger(flinger), mCount(0) { + : mFlinger(flinger) { mFlinger->incFreezeCount(); } ~FreezeLock() { mFlinger->decFreezeCount(); } - inline void incStrong(void*) const { - android_atomic_inc(&mCount); - } - inline void decStrong(void*) const { - if (android_atomic_dec(&mCount) == 1) - delete this; - } }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h index 2f617c4..0b4835e 100644 --- a/libs/surfaceflinger/Transform.h +++ b/libs/surfaceflinger/Transform.h @@ -25,7 +25,7 @@ #include <GLES/gl.h> -#include <corecg/SkMatrix.h> +#include <core/SkMatrix.h> namespace android { |