diff options
author | Mathias Agopian <mathias@google.com> | 2009-10-05 17:07:12 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-10-06 17:00:25 -0700 |
commit | 6950e428feaccc8164b989ef64e771a99948797a (patch) | |
tree | f6520613c5355eef110f3820469d7dc477598629 /libs | |
parent | 521f4f3af94e3a093a37af887d3e317a526b61a1 (diff) | |
download | frameworks_base-6950e428feaccc8164b989ef64e771a99948797a.zip frameworks_base-6950e428feaccc8164b989ef64e771a99948797a.tar.gz frameworks_base-6950e428feaccc8164b989ef64e771a99948797a.tar.bz2 |
fix [2167050] glTexImage2D code path buggy in SurfaceFlinger
When EGLImage extension is not available, SurfaceFlinger will fallback to using
glTexImage2D and glTexSubImage2D instead, which requires 50% more memory and an
extra copy. However this code path has never been exercised and had some bugs
which this patch fix.
Mainly the scale factor wasn't computed right when falling back on glDrawElements.
We also fallback to this mode of operation if a buffer doesn't have the adequate
usage bits for EGLImage usage.
This changes only code that is currently not executed. Some refactoring was needed to
keep the change clean. This doesn't change anything functionaly.
Diffstat (limited to 'libs')
-rw-r--r-- | libs/surfaceflinger/Android.mk | 2 | ||||
-rw-r--r-- | libs/surfaceflinger/Buffer.cpp | 137 | ||||
-rw-r--r-- | libs/surfaceflinger/Buffer.h | 83 | ||||
-rw-r--r-- | libs/surfaceflinger/BufferAllocator.h | 96 | ||||
-rw-r--r-- | libs/surfaceflinger/Layer.cpp | 77 | ||||
-rw-r--r-- | libs/surfaceflinger/Layer.h | 16 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.cpp | 95 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.h | 19 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBuffer.cpp | 11 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBuffer.h | 5 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerDim.cpp | 10 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 11 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.h | 3 | ||||
-rw-r--r-- | libs/ui/Android.mk | 5 | ||||
-rw-r--r-- | libs/ui/GraphicBuffer.cpp | 213 | ||||
-rw-r--r-- | libs/ui/GraphicBufferAllocator.cpp (renamed from libs/surfaceflinger/BufferAllocator.cpp) | 18 | ||||
-rw-r--r-- | libs/ui/GraphicBufferMapper.cpp (renamed from libs/ui/BufferMapper.cpp) | 16 | ||||
-rw-r--r-- | libs/ui/ISurface.cpp | 10 | ||||
-rw-r--r-- | libs/ui/Surface.cpp | 30 | ||||
-rw-r--r-- | libs/ui/SurfaceBuffer.cpp | 134 |
20 files changed, 387 insertions, 604 deletions
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index 49da111..eb51c22 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -6,8 +6,6 @@ LOCAL_SRC_FILES:= \ DisplayHardware/DisplayHardware.cpp \ DisplayHardware/DisplayHardwareBase.cpp \ BlurFilter.cpp.arm \ - Buffer.cpp \ - BufferAllocator.cpp \ Layer.cpp \ LayerBase.cpp \ LayerBuffer.cpp \ diff --git a/libs/surfaceflinger/Buffer.cpp b/libs/surfaceflinger/Buffer.cpp deleted file mode 100644 index 6190cd8..0000000 --- a/libs/surfaceflinger/Buffer.cpp +++ /dev/null @@ -1,137 +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 <utils/Errors.h> -#include <utils/Log.h> - -#include <ui/PixelFormat.h> -#include <pixelflinger/pixelflinger.h> - -#include "Buffer.h" -#include "BufferAllocator.h" - -namespace android { - -// =========================================================================== -// Buffer and implementation of android_native_buffer_t -// =========================================================================== - -Buffer::Buffer() - : SurfaceBuffer(), mInitCheck(NO_ERROR), mVStride(0) -{ -} - -Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, - uint32_t reqUsage, uint32_t flags) - : SurfaceBuffer(), mInitCheck(NO_INIT), mVStride(0) -{ - mInitCheck = initSize(w, h, format, reqUsage, flags); -} - -Buffer::~Buffer() -{ - if (handle) { - BufferAllocator& allocator(BufferAllocator::get()); - allocator.free(handle); - } -} - -status_t Buffer::initCheck() const { - return mInitCheck; -} - -android_native_buffer_t* Buffer::getNativeBuffer() const -{ - return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this)); -} - -status_t Buffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, - uint32_t reqUsage, uint32_t flags) -{ - if (handle) { - BufferAllocator& allocator(BufferAllocator::get()); - allocator.free(handle); - handle = 0; - } - return initSize(w, h, f, reqUsage, flags); -} - -status_t Buffer::initSize(uint32_t w, uint32_t h, PixelFormat format, - uint32_t reqUsage, uint32_t flags) -{ - status_t err = NO_ERROR; - - BufferAllocator& allocator = BufferAllocator::get(); - - /* - * buffers used for software rendering, but h/w composition - * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE - * - * buffers used for h/w rendering and h/w composition - * are allocated with HW_RENDER | HW_TEXTURE - * - * buffers used with h/w rendering and either NPOT or no egl_image_ext - * are allocated with SW_READ_RARELY | HW_RENDER - * - */ - - if (flags & Buffer::SECURE) { - // secure buffer, don't store it into the GPU - usage = BufferAllocator::USAGE_SW_READ_OFTEN | - BufferAllocator::USAGE_SW_WRITE_OFTEN; - } else { - // it's allowed to modify the usage flags here, but generally - // the requested flags should be honored. - usage = reqUsage | BufferAllocator::USAGE_HW_TEXTURE; - } - - if (format == PIXEL_FORMAT_RGBX_8888) - format = PIXEL_FORMAT_RGBA_8888; - - err = allocator.alloc(w, h, format, usage, &handle, &stride); - if (err == NO_ERROR) { - this->width = w; - this->height = h; - this->format = format; - mVStride = 0; - } - - return err; -} - -status_t Buffer::lock(GGLSurface* sur, uint32_t usage) -{ - void* vaddr; - status_t res = SurfaceBuffer::lock(usage, &vaddr); - if (res == NO_ERROR && sur) { - sur->version = sizeof(GGLSurface); - sur->width = width; - sur->height = height; - sur->stride = stride; - sur->format = format; - sur->vstride = mVStride; - sur->data = static_cast<GGLubyte*>(vaddr); - } - return res; -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/Buffer.h b/libs/surfaceflinger/Buffer.h deleted file mode 100644 index 203da3b..0000000 --- a/libs/surfaceflinger/Buffer.h +++ /dev/null @@ -1,83 +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_BITMAP_H -#define ANDROID_LAYER_BITMAP_H - -#include <stdint.h> -#include <sys/types.h> - -#include <ui/PixelFormat.h> -#include <ui/Rect.h> -#include <pixelflinger/pixelflinger.h> -#include <private/ui/SurfaceBuffer.h> - -struct android_native_buffer_t; - -namespace android { - -// =========================================================================== -// Buffer -// =========================================================================== - -class Buffer : public SurfaceBuffer -{ -public: - enum { - DONT_CLEAR = 0x00000001, - SECURE = 0x00000004 - }; - - Buffer(); - - // creates w * h buffer - Buffer(uint32_t w, uint32_t h, PixelFormat format, - uint32_t reqUsage, uint32_t flags = 0); - - // return status - status_t initCheck() const; - - uint32_t getWidth() const { return width; } - uint32_t getHeight() const { return height; } - uint32_t getStride() const { return stride; } - uint32_t getUsage() const { return usage; } - PixelFormat getPixelFormat() const { return format; } - Rect getBounds() const { return Rect(width, height); } - - status_t lock(GGLSurface* surface, uint32_t usage); - - android_native_buffer_t* getNativeBuffer() const; - - status_t reallocate(uint32_t w, uint32_t h, PixelFormat f, - uint32_t reqUsage, uint32_t flags); - -private: - friend class LightRefBase<Buffer>; - Buffer(const Buffer& rhs); - virtual ~Buffer(); - Buffer& operator = (const Buffer& rhs); - const Buffer& operator = (const Buffer& rhs) const; - - status_t initSize(uint32_t w, uint32_t h, PixelFormat format, - uint32_t reqUsage, uint32_t flags); - - ssize_t mInitCheck; - uint32_t mVStride; -}; - -}; // namespace android - -#endif // ANDROID_LAYER_BITMAP_H diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h deleted file mode 100644 index a279ded..0000000 --- a/libs/surfaceflinger/BufferAllocator.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -** -** Copyright 2009, 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_BUFFER_ALLOCATOR_H -#define ANDROID_BUFFER_ALLOCATOR_H - -#include <stdint.h> - -#include <cutils/native_handle.h> - -#include <utils/Errors.h> -#include <utils/KeyedVector.h> -#include <utils/threads.h> -#include <utils/Singleton.h> - -#include <ui/PixelFormat.h> - -#include <hardware/gralloc.h> - - -namespace android { -// --------------------------------------------------------------------------- - -class String8; - -class BufferAllocator : public Singleton<BufferAllocator> -{ -public: - enum { - USAGE_SW_READ_NEVER = GRALLOC_USAGE_SW_READ_NEVER, - USAGE_SW_READ_RARELY = GRALLOC_USAGE_SW_READ_RARELY, - USAGE_SW_READ_OFTEN = GRALLOC_USAGE_SW_READ_OFTEN, - USAGE_SW_READ_MASK = GRALLOC_USAGE_SW_READ_MASK, - - USAGE_SW_WRITE_NEVER = GRALLOC_USAGE_SW_WRITE_NEVER, - USAGE_SW_WRITE_RARELY = GRALLOC_USAGE_SW_WRITE_RARELY, - USAGE_SW_WRITE_OFTEN = GRALLOC_USAGE_SW_WRITE_OFTEN, - USAGE_SW_WRITE_MASK = GRALLOC_USAGE_SW_WRITE_MASK, - - USAGE_SOFTWARE_MASK = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK, - - USAGE_HW_TEXTURE = GRALLOC_USAGE_HW_TEXTURE, - USAGE_HW_RENDER = GRALLOC_USAGE_HW_RENDER, - USAGE_HW_2D = GRALLOC_USAGE_HW_2D, - USAGE_HW_MASK = GRALLOC_USAGE_HW_MASK - }; - - static inline BufferAllocator& get() { return getInstance(); } - - - status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, - buffer_handle_t* handle, int32_t* stride); - - status_t free(buffer_handle_t handle); - - void dump(String8& res) const; - -private: - struct alloc_rec_t { - uint32_t w; - uint32_t h; - PixelFormat format; - uint32_t usage; - void* vaddr; - size_t size; - }; - - static Mutex sLock; - static KeyedVector<buffer_handle_t, alloc_rec_t> sAllocList; - - friend class Singleton<BufferAllocator>; - BufferAllocator(); - ~BufferAllocator(); - - mutable Mutex mLock; - alloc_device_t *mAllocDev; -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_BUFFER_ALLOCATOR_H diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 13201db..c1f7f27 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -25,10 +25,10 @@ #include <utils/Log.h> #include <utils/StopWatch.h> +#include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <ui/Surface.h> -#include "Buffer.h" #include "clz.h" #include "Layer.h" #include "SurfaceFlinger.h" @@ -109,14 +109,10 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(), &displayInfo); - uint32_t bufferFlags = 0; - if (flags & ISurfaceComposer::eSecure) - bufferFlags |= Buffer::SECURE; - mFormat = format; mWidth = w; mHeight = h; - mSecure = (bufferFlags & Buffer::SECURE) ? true : false; + mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; // we use the red index @@ -124,9 +120,8 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = layerRedsize > displayRedSize; - mBufferFlags = bufferFlags; for (size_t i=0 ; i<NUM_BUFFERS ; i++) { - mBuffers[i] = new Buffer(); + mBuffers[i] = new GraphicBuffer(); } mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); return NO_ERROR; @@ -135,8 +130,9 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, void Layer::reloadTexture(const Region& dirty) { Mutex::Autolock _l(mLock); - sp<Buffer> buffer(getFrontBuffer()); - if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { + sp<GraphicBuffer> buffer(getFrontBuffer()); + if (LIKELY((mFlags & DisplayHardware::DIRECT_TEXTURE) && + (buffer->usage & GRALLOC_USAGE_HW_TEXTURE))) { int index = mFrontBufferIndex; if (LIKELY(!mTextures[index].dirty)) { glBindTexture(GL_TEXTURE_2D, mTextures[index].name); @@ -187,6 +183,7 @@ void Layer::reloadTexture(const Region& dirty) mFlags &= ~DisplayHardware::DIRECT_TEXTURE; } else { // Everything went okay! + mTextures[index].NPOTAdjust = false; mTextures[index].dirty = false; mTextures[index].width = clientBuf->width; mTextures[index].height = clientBuf->height; @@ -194,15 +191,21 @@ void Layer::reloadTexture(const Region& dirty) } } } else { + for (int i=0 ; i<NUM_BUFFERS ; i++) + mTextures[i].image = EGL_NO_IMAGE_KHR; + GGLSurface t; - status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); + status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); LOGE_IF(res, "error %d (%s) locking buffer %p", res, strerror(res), buffer.get()); + if (res == NO_ERROR) { if (UNLIKELY(mTextures[0].name == -1U)) { mTextures[0].name = createTexture(); + mTextures[0].width = 0; + mTextures[0].height = 0; } - loadTexture(&mTextures[0], mTextures[0].name, dirty, t); + loadTexture(&mTextures[0], dirty, t); buffer->unlock(); } } @@ -211,8 +214,9 @@ void Layer::reloadTexture(const Region& dirty) void Layer::onDraw(const Region& clip) const { - const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ? - mFrontBufferIndex : 0; + int index = mFrontBufferIndex; + if (mTextures[index].image == EGL_NO_IMAGE_KHR) + index = 0; GLuint textureName = mTextures[index].name; if (UNLIKELY(textureName == -1LU)) { // the texture has not been created yet, this Layer has @@ -224,9 +228,9 @@ void Layer::onDraw(const Region& clip) const drawWithOpenGL(clip, mTextures[index]); } -sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage) +sp<GraphicBuffer> Layer::requestBuffer(int index, int usage) { - sp<Buffer> buffer; + sp<GraphicBuffer> buffer; // this ensures our client doesn't go away while we're accessing // the shared area. @@ -269,14 +273,15 @@ sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage) mBuffers[index].clear(); } + const uint32_t effectiveUsage = getEffectiveUsage(usage); if (buffer!=0 && buffer->getStrongCount() == 1) { - err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags); + err = buffer->reallocate(w, h, mFormat, effectiveUsage); } else { // here we have to reallocate a new buffer because we could have a // client in our process with a reference to it (eg: status bar), // and we can't release the handle under its feet. buffer.clear(); - buffer = new Buffer(w, h, mFormat, usage, mBufferFlags); + buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage); err = buffer->initCheck(); } @@ -305,6 +310,32 @@ sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage) return buffer; } +uint32_t Layer::getEffectiveUsage(uint32_t usage) const +{ + /* + * buffers used for software rendering, but h/w composition + * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE + * + * buffers used for h/w rendering and h/w composition + * are allocated with HW_RENDER | HW_TEXTURE + * + * buffers used with h/w rendering and either NPOT or no egl_image_ext + * are allocated with SW_READ_RARELY | HW_RENDER + * + */ + + if (mSecure) { + // secure buffer, don't store it into the GPU + usage = GraphicBuffer::USAGE_SW_READ_OFTEN | + GraphicBuffer::USAGE_SW_WRITE_OFTEN; + } else { + // it's allowed to modify the usage flags here, but generally + // the requested flags should be honored. + usage |= GraphicBuffer::USAGE_HW_TEXTURE; + } + return usage; +} + uint32_t Layer::doTransaction(uint32_t flags) { const Layer::State& front(drawingState()); @@ -383,7 +414,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) mFrontBufferIndex = buf; // get the dirty region - sp<Buffer> newFrontBuffer(getBuffer(buf)); + sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); const Region dirty(lcblk->getDirtyRegion(buf)); mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); @@ -421,7 +452,9 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // FIXME: signal an event if we have more buffers waiting // mFlinger->signalEvent(); - reloadTexture( mPostedDirtyRegion ); + if (!mPostedDirtyRegion.isEmpty()) { + reloadTexture( mPostedDirtyRegion ); + } } void Layer::unlockPageFlip( @@ -465,9 +498,9 @@ Layer::SurfaceLayer::~SurfaceLayer() { } -sp<SurfaceBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) +sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage) { - sp<SurfaceBuffer> buffer; + sp<GraphicBuffer> buffer; sp<Layer> owner(getOwner()); if (owner != 0) { LOGE_IF(uint32_t(index)>=NUM_BUFFERS, diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index f111840..e176cfc 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -20,6 +20,7 @@ #include <stdint.h> #include <sys/types.h> +#include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <pixelflinger/pixelflinger.h> @@ -28,7 +29,6 @@ #include <GLES/gl.h> #include <GLES/glext.h> -#include "Buffer.h" #include "LayerBase.h" #include "Transform.h" @@ -38,7 +38,6 @@ namespace android { class Client; class FreezeLock; -class Buffer; // --------------------------------------------------------------------------- @@ -74,20 +73,22 @@ public: virtual status_t ditch(); // only for debugging - inline sp<Buffer> getBuffer(int i) { return mBuffers[i]; } + inline sp<GraphicBuffer> getBuffer(int i) { return mBuffers[i]; } // only for debugging inline const sp<FreezeLock>& getFreezeLock() const { return mFreezeLock; } // only for debugging inline PixelFormat pixelFormat() const { return mFormat; } private: - inline sp<Buffer> getFrontBuffer() { + inline sp<GraphicBuffer> getFrontBuffer() { return mBuffers[mFrontBufferIndex]; } void reloadTexture(const Region& dirty); - sp<SurfaceBuffer> requestBuffer(int index, int usage); + uint32_t getEffectiveUsage(uint32_t usage) const; + + sp<GraphicBuffer> requestBuffer(int index, int usage); void destroy(); class SurfaceLayer : public LayerBaseClient::Surface { @@ -96,7 +97,7 @@ private: SurfaceID id, const sp<Layer>& owner); ~SurfaceLayer(); private: - virtual sp<SurfaceBuffer> requestBuffer(int index, int usage); + virtual sp<GraphicBuffer> requestBuffer(int index, int usage); sp<Layer> getOwner() const { return static_cast<Layer*>(Surface::getOwner().get()); } @@ -112,10 +113,9 @@ private: Region mPostedDirtyRegion; sp<FreezeLock> mFreezeLock; PixelFormat mFormat; - uint32_t mBufferFlags; // protected by mLock - sp<Buffer> mBuffers[NUM_BUFFERS]; + sp<GraphicBuffer> mBuffers[NUM_BUFFERS]; Texture mTextures[NUM_BUFFERS]; uint32_t mWidth; uint32_t mHeight; diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 83814cc..b376e72 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -449,17 +449,9 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glTranslatef(0, 1, 0); glRotatef(-90, 0, 0, 1); } - - if (!(mFlags & (DisplayHardware::NPOT_EXTENSION | - DisplayHardware::DIRECT_TEXTURE))) { - // find the smallest power-of-two that will accommodate our surface - GLuint tw = 1 << (31 - clz(width)); - GLuint th = 1 << (31 - clz(height)); - if (tw < width) tw <<= 1; - if (th < height) th <<= 1; - GLfloat ws = GLfloat(width) /tw; - GLfloat hs = GLfloat(height)/th; - glScalef(ws, hs, 1.0f); + + if (texture.NPOTAdjust) { + glScalef(texture.wScale, texture.hScale, 1.0f); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -508,21 +500,15 @@ void LayerBase::validateTexture(GLint textureName) const } } -void LayerBase::loadTexture(Texture* texture, GLint textureName, +void LayerBase::loadTexture(Texture* texture, const Region& dirty, const GGLSurface& t) const { - // TODO: defer the actual texture reload until LayerBase::validateTexture - // is called. - - texture->name = textureName; - GLuint& textureWidth(texture->width); - GLuint& textureHeight(texture->height); + if (texture->name == -1U) { + // uh? + return; + } - uint32_t flags = mFlags; - glBindTexture(GL_TEXTURE_2D, textureName); - - GLuint tw = t.width; - GLuint th = t.height; + glBindTexture(GL_TEXTURE_2D, texture->name); /* * In OpenGL ES we can't specify a stride with glTexImage2D (however, @@ -547,64 +533,63 @@ void LayerBase::loadTexture(Texture* texture, GLint textureName, /* * round to POT if needed */ + if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { + texture->NPOTAdjust = true; + } - GLuint texture_w = tw; - GLuint texture_h = th; - if (!(flags & DisplayHardware::NPOT_EXTENSION)) { + if (texture->NPOTAdjust) { // find the smallest power-of-two that will accommodate our surface - texture_w = 1 << (31 - clz(t.width)); - texture_h = 1 << (31 - clz(t.height)); - if (texture_w < t.width) texture_w <<= 1; - if (texture_h < t.height) texture_h <<= 1; + texture->potWidth = 1 << (31 - clz(t.width)); + texture->potHeight = 1 << (31 - clz(t.height)); + if (texture->potWidth < t.width) texture->potWidth <<= 1; + if (texture->potHeight < t.height) texture->potHeight <<= 1; + texture->wScale = float(t.width) / texture->potWidth; + texture->hScale = float(t.height) / texture->potHeight; + } else { + texture->potWidth = t.width; + texture->potHeight = t.height; } - -regular: + Rect bounds(dirty.bounds()); GLvoid* data = 0; - if (texture_w!=textureWidth || texture_h!=textureHeight) { - // texture size changed, we need to create a new one + if (texture->width != t.width || texture->height != t.height) { + texture->width = t.width; + texture->height = t.height; - if (!textureWidth || !textureHeight) { - // this is the first time, load the whole texture - if (texture_w==tw && texture_h==th) { - // we can do it one pass - data = t.data; - } else { - // we have to create the texture first because it - // doesn't match the size of the buffer - bounds.set(Rect(tw, th)); - } + // texture size changed, we need to create a new one + bounds.set(Rect(t.width, t.height)); + if (t.width == texture->potWidth && + t.height == texture->potHeight) { + // we can do it one pass + data = t.data; } - + if (t.format == GGL_PIXEL_FORMAT_RGB_565) { glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGB, texture_w, texture_h, 0, + GL_RGB, texture->potWidth, texture->potHeight, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) { glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, texture_w, texture_h, 0, + GL_RGBA, texture->potWidth, texture->potHeight, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888 || t.format == GGL_PIXEL_FORMAT_RGBX_8888) { glTexImage2D(GL_TEXTURE_2D, 0, - GL_RGBA, texture_w, texture_h, 0, + GL_RGBA, texture->potWidth, texture->potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP || t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) { // just show the Y plane of YUV buffers glTexImage2D(GL_TEXTURE_2D, 0, - GL_LUMINANCE, texture_w, texture_h, 0, + GL_LUMINANCE, texture->potWidth, texture->potHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); } else { // oops, we don't handle this format! LOGE("layer %p, texture=%d, using format %d, which is not " - "supported by the GL", this, textureName, t.format); - textureName = -1; + "supported by the GL", this, texture->name, t.format); } - textureWidth = texture_w; - textureHeight = texture_h; } - if (!data && textureName>=0) { + if (!data) { if (t.format == GGL_PIXEL_FORMAT_RGB_565) { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.top, t.width, bounds.height(), @@ -747,7 +732,7 @@ status_t LayerBaseClient::Surface::onTransact( return BnSurface::onTransact(code, data, reply, flags); } -sp<SurfaceBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) +sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) { return NULL; } diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 0dfa4fe..efa4f8c 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -39,12 +39,11 @@ namespace android { // --------------------------------------------------------------------------- -class SurfaceFlinger; class DisplayHardware; -class GraphicPlane; class Client; -class SurfaceBuffer; -class Buffer; +class GraphicBuffer; +class GraphicPlane; +class SurfaceFlinger; // --------------------------------------------------------------------------- @@ -241,12 +240,18 @@ protected: struct Texture { Texture() : name(-1U), width(0), height(0), - image(EGL_NO_IMAGE_KHR), transform(0), dirty(true) { } + image(EGL_NO_IMAGE_KHR), transform(0), + NPOTAdjust(false), dirty(true) { } GLuint name; GLuint width; GLuint height; + GLuint potWidth; + GLuint potHeight; + GLfloat wScale; + GLfloat hScale; EGLImageKHR image; uint32_t transform; + bool NPOTAdjust; bool dirty; }; @@ -254,7 +259,7 @@ protected: GLclampx b, GLclampx alpha) const; void clearWithOpenGL(const Region& clip) const; void drawWithOpenGL(const Region& clip, const Texture& texture) const; - void loadTexture(Texture* texture, GLint textureName, + void loadTexture(Texture* texture, const Region& dirty, const GGLSurface& t) const; @@ -339,7 +344,7 @@ public: sp<LayerBaseClient> getOwner() const; private: - virtual sp<SurfaceBuffer> requestBuffer(int index, int usage); + virtual sp<GraphicBuffer> requestBuffer(int index, int usage); virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); virtual void postBuffer(ssize_t offset); virtual void unregisterBuffers(); diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 667571b..7e27a02 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -23,13 +23,12 @@ #include <utils/Log.h> #include <utils/StopWatch.h> +#include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <ui/FramebufferNativeWindow.h> #include <hardware/copybit.h> -#include "Buffer.h" -#include "BufferAllocator.h" #include "LayerBuffer.h" #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" @@ -474,9 +473,9 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const mTempBitmap->getWidth() < size_t(tmp_w) || mTempBitmap->getHeight() < size_t(tmp_h)) { mTempBitmap.clear(); - mTempBitmap = new android::Buffer( - tmp_w, tmp_h, src.img.format, - BufferAllocator::USAGE_HW_2D); + mTempBitmap = new GraphicBuffer( + tmp_w, tmp_h, src.img.format, + GraphicBuffer::USAGE_HW_2D); err = mTempBitmap->initCheck(); } @@ -549,7 +548,7 @@ void LayerBuffer::BufferSource::onDraw(const Region& clip) const t.format = src.img.format; t.data = (GGLubyte*)src.img.base; const Region dirty(Rect(t.width, t.height)); - mLayer.loadTexture(&mTexture, mTexture.name, dirty, t); + mLayer.loadTexture(&mTexture, dirty, t); mTexture.transform = mBufferHeap.transform; mLayer.drawWithOpenGL(clip, mTexture); } diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index 0452818..5eb472c 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -20,9 +20,6 @@ #include <stdint.h> #include <sys/types.h> -#include <binder/IMemory.h> -#include <private/ui/LayerState.h> - #include "LayerBase.h" struct copybit_device_t; @@ -133,7 +130,7 @@ private: status_t mStatus; ISurface::BufferHeap mBufferHeap; size_t mBufferSize; - mutable sp<android::Buffer> mTempBitmap; + mutable sp<GraphicBuffer> mTempBitmap; mutable LayerBase::Texture mTexture; copybit_device_t* mBlitEngine; }; diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 8ba0a9d..538dc77 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -21,8 +21,8 @@ #include <utils/Errors.h> #include <utils/Log.h> -#include "Buffer.h" -#include "BufferAllocator.h" +#include <ui/GraphicBuffer.h> + #include "LayerDim.h" #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" @@ -70,9 +70,9 @@ void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h) if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) { // TODO: api to pass the usage flags - sp<Buffer> buffer = new Buffer(w, h, PIXEL_FORMAT_RGB_565, - BufferAllocator::USAGE_SW_WRITE_OFTEN | - BufferAllocator::USAGE_HW_TEXTURE); + sp<GraphicBuffer> buffer = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_565, + GraphicBuffer::USAGE_SW_WRITE_OFTEN | + GraphicBuffer::USAGE_HW_TEXTURE); android_native_buffer_t* clientBuf = buffer->getNativeBuffer(); diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index f2b918f..9694cf1 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -37,6 +37,7 @@ #include <utils/String16.h> #include <utils/StopWatch.h> +#include <ui/GraphicBufferAllocator.h> #include <ui/PixelFormat.h> #include <ui/DisplayInfo.h> @@ -44,8 +45,6 @@ #include <GLES/gl.h> #include "clz.h" -#include "Buffer.h" -#include "BufferAllocator.h" #include "Layer.h" #include "LayerBlur.h" #include "LayerBuffer.h" @@ -190,6 +189,7 @@ SurfaceFlinger::SurfaceFlinger() mLastSwapBufferTime(0), mDebugInTransaction(0), mLastTransactionTime(0), + mBootFinished(false), mConsoleSignals(0), mSecureFrameBuffer(0) { @@ -294,6 +294,7 @@ void SurfaceFlinger::bootFinished() const nsecs_t now = systemTime(); const nsecs_t duration = now - mBootTime; LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); + mBootFinished = true; property_set("ctl.stop", "bootanim"); } @@ -1521,8 +1522,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) if (l != 0) { SharedBufferStack::Statistics stats = l->lcblk->getStats(); result.append( l->lcblk->dump(" ") ); - sp<const Buffer> buf0(l->getBuffer(0)); - sp<const Buffer> buf1(l->getBuffer(1)); + sp<const GraphicBuffer> buf0(l->getBuffer(0)); + sp<const GraphicBuffer> buf1(l->getBuffer(1)); uint32_t w0=0, h0=0, s0=0; uint32_t w1=0, h1=0, s1=0; if (buf0 != 0) { @@ -1573,7 +1574,7 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) } snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size()); result.append(buffer); - const BufferAllocator& alloc(BufferAllocator::get()); + const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); alloc.dump(result); if (locked) { diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index e446070..6698e00 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -293,7 +293,7 @@ private: inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; } inline bool hasFreezeRequest() const { return mFreezeDisplay; } inline bool isFrozen() const { - return mFreezeDisplay || mFreezeCount>0; + return (mFreezeDisplay || mFreezeCount>0) && mBootFinished; } @@ -351,6 +351,7 @@ private: nsecs_t mLastSwapBufferTime; volatile nsecs_t mDebugInTransaction; nsecs_t mLastTransactionTime; + bool mBootFinished; // these are thread safe mutable Barrier mReadyToRunBarrier; diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 9577044..73d86ea 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -2,13 +2,15 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - BufferMapper.cpp \ Camera.cpp \ CameraParameters.cpp \ EGLUtils.cpp \ EventHub.cpp \ EventRecurrence.cpp \ FramebufferNativeWindow.cpp \ + GraphicBuffer.cpp \ + GraphicBufferAllocator.cpp \ + GraphicBufferMapper.cpp \ KeyLayoutMap.cpp \ KeyCharacterMap.cpp \ ICamera.cpp \ @@ -25,7 +27,6 @@ LOCAL_SRC_FILES:= \ Region.cpp \ SharedBufferStack.cpp \ Surface.cpp \ - SurfaceBuffer.cpp \ SurfaceComposerClient.cpp \ SurfaceFlingerSynchro.cpp diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp new file mode 100644 index 0000000..1cf20d7 --- /dev/null +++ b/libs/ui/GraphicBuffer.cpp @@ -0,0 +1,213 @@ +/* + * 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 <binder/Parcel.h> + +#include <utils/Errors.h> +#include <utils/Log.h> + +#include <ui/GraphicBuffer.h> +#include <ui/GraphicBufferAllocator.h> +#include <ui/GraphicBufferMapper.h> +#include <ui/PixelFormat.h> + +#include <pixelflinger/pixelflinger.h> + +namespace android { + +// =========================================================================== +// Buffer and implementation of android_native_buffer_t +// =========================================================================== + +GraphicBuffer::GraphicBuffer() + : BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) +{ + width = + height = + stride = + format = + usage = 0; + handle = NULL; +} + +GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, + PixelFormat reqFormat, uint32_t reqUsage) + : BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) +{ + width = + height = + stride = + format = + usage = 0; + handle = NULL; + mInitCheck = initSize(w, h, reqFormat, reqUsage); +} + +GraphicBuffer::GraphicBuffer(const Parcel& data) + : BASE(), mOwner(true), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mVStride(0), mIndex(-1) +{ + // we own the handle in this case + width = data.readInt32(); + if (width < 0) { + width = height = stride = format = usage = 0; + handle = 0; + } else { + height = data.readInt32(); + stride = data.readInt32(); + format = data.readInt32(); + usage = data.readInt32(); + handle = data.readNativeHandle(); + } +} + +GraphicBuffer::~GraphicBuffer() +{ + if (handle) { + if (mOwner) { + native_handle_close(handle); + native_handle_delete(const_cast<native_handle*>(handle)); + } else { + GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); + allocator.free(handle); + } + } +} + +status_t GraphicBuffer::initCheck() const { + return mInitCheck; +} + +android_native_buffer_t* GraphicBuffer::getNativeBuffer() const +{ + return static_cast<android_native_buffer_t*>( + const_cast<GraphicBuffer*>(this)); +} + +status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f, + uint32_t reqUsage) +{ + if (handle) { + GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); + allocator.free(handle); + handle = 0; + } + return initSize(w, h, f, reqUsage); +} + +status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, + uint32_t reqUsage) +{ + if (format == PIXEL_FORMAT_RGBX_8888) + format = PIXEL_FORMAT_RGBA_8888; + + GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); + status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride); + if (err == NO_ERROR) { + this->width = w; + this->height = h; + this->format = format; + this->usage = reqUsage; + mVStride = 0; + } + return err; +} + +status_t GraphicBuffer::lock(uint32_t usage, void** vaddr) +{ + const Rect lockBounds(width, height); + status_t res = lock(usage, lockBounds, vaddr); + return res; +} + +status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) +{ + if (rect.left < 0 || rect.right > this->width || + rect.top < 0 || rect.bottom > this->height) { + LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", + rect.left, rect.top, rect.right, rect.bottom, + this->width, this->height); + return BAD_VALUE; + } + status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); + return res; +} + +status_t GraphicBuffer::unlock() +{ + status_t res = getBufferMapper().unlock(handle); + return res; +} + +status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage) +{ + void* vaddr; + status_t res = GraphicBuffer::lock(usage, &vaddr); + if (res == NO_ERROR && sur) { + sur->version = sizeof(GGLSurface); + sur->width = width; + sur->height = height; + sur->stride = stride; + sur->format = format; + sur->vstride = mVStride; + sur->data = static_cast<GGLubyte*>(vaddr); + } + return res; +} + + +status_t GraphicBuffer::writeToParcel(Parcel* reply, + android_native_buffer_t const* buffer) +{ + if (buffer == NULL) + return BAD_VALUE; + + if (buffer->width < 0 || buffer->height < 0) + return BAD_VALUE; + + status_t err = NO_ERROR; + if (buffer->handle == NULL) { + // this buffer doesn't have a handle + reply->writeInt32(NO_MEMORY); + } else { + reply->writeInt32(buffer->width); + reply->writeInt32(buffer->height); + reply->writeInt32(buffer->stride); + reply->writeInt32(buffer->format); + reply->writeInt32(buffer->usage); + err = reply->writeNativeHandle(buffer->handle); + } + return err; +} + + +void GraphicBuffer::setIndex(int index) { + mIndex = index; +} + +int GraphicBuffer::getIndex() const { + return mIndex; +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index 3e37bc3..10b1051 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -20,18 +20,18 @@ #include <utils/Singleton.h> #include <utils/String8.h> -#include "BufferAllocator.h" +#include <ui/GraphicBufferAllocator.h> namespace android { // --------------------------------------------------------------------------- -ANDROID_SINGLETON_STATIC_INSTANCE( BufferAllocator ) +ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator ) -Mutex BufferAllocator::sLock; -KeyedVector<buffer_handle_t, BufferAllocator::alloc_rec_t> BufferAllocator::sAllocList; +Mutex GraphicBufferAllocator::sLock; +KeyedVector<buffer_handle_t, GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList; -BufferAllocator::BufferAllocator() +GraphicBufferAllocator::GraphicBufferAllocator() : mAllocDev(0) { hw_module_t const* module; @@ -42,12 +42,12 @@ BufferAllocator::BufferAllocator() } } -BufferAllocator::~BufferAllocator() +GraphicBufferAllocator::~GraphicBufferAllocator() { gralloc_close(mAllocDev); } -void BufferAllocator::dump(String8& result) const +void GraphicBufferAllocator::dump(String8& result) const { Mutex::Autolock _l(sLock); KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); @@ -73,7 +73,7 @@ static inline uint32_t clamp(uint32_t c) { return c>0 ? c : 1; } -status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, +status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, buffer_handle_t* handle, int32_t* stride) { Mutex::Autolock _l(mLock); @@ -109,7 +109,7 @@ status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, return err; } -status_t BufferAllocator::free(buffer_handle_t handle) +status_t GraphicBufferAllocator::free(buffer_handle_t handle) { Mutex::Autolock _l(mLock); diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp index 4add8f9..dd529e6 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/GraphicBufferMapper.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define LOG_TAG "BufferMapper" +#define LOG_TAG "GraphicBufferMapper" #include <stdint.h> #include <errno.h> @@ -22,7 +22,7 @@ #include <utils/Errors.h> #include <utils/Log.h> -#include <ui/BufferMapper.h> +#include <ui/GraphicBufferMapper.h> #include <ui/Rect.h> #include <hardware/gralloc.h> @@ -31,9 +31,9 @@ namespace android { // --------------------------------------------------------------------------- -ANDROID_SINGLETON_STATIC_INSTANCE( BufferMapper ) +ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper ) -BufferMapper::BufferMapper() +GraphicBufferMapper::GraphicBufferMapper() : mAllocMod(0) { hw_module_t const* module; @@ -44,7 +44,7 @@ BufferMapper::BufferMapper() } } -status_t BufferMapper::registerBuffer(buffer_handle_t handle) +status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) { status_t err = mAllocMod->registerBuffer(mAllocMod, handle); LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", @@ -52,7 +52,7 @@ status_t BufferMapper::registerBuffer(buffer_handle_t handle) return err; } -status_t BufferMapper::unregisterBuffer(buffer_handle_t handle) +status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) { status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle); LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", @@ -60,7 +60,7 @@ status_t BufferMapper::unregisterBuffer(buffer_handle_t handle) return err; } -status_t BufferMapper::lock(buffer_handle_t handle, +status_t GraphicBufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds, void** vaddr) { status_t err = mAllocMod->lock(mAllocMod, handle, usage, @@ -69,7 +69,7 @@ status_t BufferMapper::lock(buffer_handle_t handle, return err; } -status_t BufferMapper::unlock(buffer_handle_t handle) +status_t GraphicBufferMapper::unlock(buffer_handle_t handle) { status_t err = mAllocMod->unlock(mAllocMod, handle); LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp index a2dbe7f..4fb38ed 100644 --- a/libs/ui/ISurface.cpp +++ b/libs/ui/ISurface.cpp @@ -27,7 +27,7 @@ #include <ui/Overlay.h> #include <ui/Surface.h> -#include <private/ui/SurfaceBuffer.h> +#include <ui/GraphicBuffer.h> namespace android { @@ -71,14 +71,14 @@ public: { } - virtual sp<SurfaceBuffer> requestBuffer(int bufferIdx, int usage) + virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) { Parcel data, reply; data.writeInterfaceToken(ISurface::getInterfaceDescriptor()); data.writeInt32(bufferIdx); data.writeInt32(usage); remote()->transact(REQUEST_BUFFER, data, &reply); - sp<SurfaceBuffer> buffer = new SurfaceBuffer(reply); + sp<GraphicBuffer> buffer = new GraphicBuffer(reply); return buffer; } @@ -139,8 +139,8 @@ status_t BnSurface::onTransact( CHECK_INTERFACE(ISurface, data, reply); int bufferIdx = data.readInt32(); int usage = data.readInt32(); - sp<SurfaceBuffer> buffer(requestBuffer(bufferIdx, usage)); - return SurfaceBuffer::writeToParcel(reply, buffer.get()); + sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage)); + return GraphicBuffer::writeToParcel(reply, buffer.get()); } case REGISTER_BUFFERS: { CHECK_INTERFACE(ISurface, data, reply); diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 285edb4..7822533 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -31,7 +31,8 @@ #include <utils/Log.h> #include <ui/DisplayInfo.h> -#include <ui/BufferMapper.h> +#include <ui/GraphicBuffer.h> +#include <ui/GraphicBufferMapper.h> #include <ui/ISurface.h> #include <ui/Surface.h> #include <ui/SurfaceComposerClient.h> @@ -41,15 +42,14 @@ #include <private/ui/SharedBufferStack.h> #include <private/ui/LayerState.h> -#include <private/ui/SurfaceBuffer.h> namespace android { // ---------------------------------------------------------------------- static status_t copyBlt( - const sp<SurfaceBuffer>& dst, - const sp<SurfaceBuffer>& src, + const sp<GraphicBuffer>& dst, + const sp<GraphicBuffer>& src, const Region& reg) { status_t err; @@ -310,7 +310,7 @@ Surface::Surface(const sp<SurfaceControl>& surface) : mClient(surface->mClient), mSurface(surface->mSurface), mToken(surface->mToken), mIdentity(surface->mIdentity), mFormat(surface->mFormat), mFlags(surface->mFlags), - mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL), + mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL), mWidth(surface->mWidth), mHeight(surface->mHeight) { mSharedBufferClient = new SharedBufferClient( @@ -320,7 +320,7 @@ Surface::Surface(const sp<SurfaceControl>& surface) } Surface::Surface(const Parcel& parcel) - : mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL) + : mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL) { sp<IBinder> clientBinder = parcel.readStrongBinder(); mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); @@ -473,11 +473,11 @@ int Surface::perform(android_native_window_t* window, // ---------------------------------------------------------------------------- -status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer) { +status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) { android_native_buffer_t* out; status_t err = dequeueBuffer(&out); if (err == NO_ERROR) { - *buffer = SurfaceBuffer::getSelf(out); + *buffer = GraphicBuffer::getSelf(out); } return err; } @@ -500,7 +500,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) // below we make sure we AT LEAST have the usage flags we want const uint32_t usage(getUsage()); - const sp<SurfaceBuffer>& backBuffer(mBuffers[bufIdx]); + const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]); if (backBuffer == 0 || ((uint32_t(backBuffer->usage) & usage) != usage) || mSharedBufferClient->needNewBuffer(bufIdx)) @@ -537,7 +537,7 @@ int Surface::lockBuffer(android_native_buffer_t* buffer) if (err != NO_ERROR) return err; - int32_t bufIdx = SurfaceBuffer::getSelf(buffer)->getIndex(); + int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex(); err = mSharedBufferClient->lock(bufIdx); LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err)); return err; @@ -554,7 +554,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) mDirtyRegion.set(mSwapRectangle); } - int32_t bufIdx = SurfaceBuffer::getSelf(buffer)->getIndex(); + int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex(); mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion); err = mSharedBufferClient->queue(bufIdx); LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err)); @@ -627,7 +627,7 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) // we're intending to do software rendering from this point setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); - sp<SurfaceBuffer> backBuffer; + sp<GraphicBuffer> backBuffer; status_t err = dequeueBuffer(&backBuffer); LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); if (err == NO_ERROR) { @@ -652,7 +652,7 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) newDirtyRegion.andSelf(bounds); } - const sp<SurfaceBuffer>& frontBuffer(mPostedBuffer); + const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); if (frontBuffer !=0 && backBuffer->width == frontBuffer->width && backBuffer->height == frontBuffer->height && @@ -721,13 +721,13 @@ status_t Surface::getBufferLocked(int index, int usage) status_t err = NO_MEMORY; // free the current buffer - sp<SurfaceBuffer>& currentBuffer(mBuffers[index]); + sp<GraphicBuffer>& currentBuffer(mBuffers[index]); if (currentBuffer != 0) { getBufferMapper().unregisterBuffer(currentBuffer->handle); currentBuffer.clear(); } - sp<SurfaceBuffer> buffer = s->requestBuffer(index, usage); + sp<GraphicBuffer> buffer = s->requestBuffer(index, usage); LOGE_IF(buffer==0, "ISurface::getBuffer(%d, %08x) returned NULL", index, usage); diff --git a/libs/ui/SurfaceBuffer.cpp b/libs/ui/SurfaceBuffer.cpp deleted file mode 100644 index 0510bc1..0000000 --- a/libs/ui/SurfaceBuffer.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -#define LOG_TAG "SurfaceBuffer" - -#include <stdint.h> -#include <errno.h> -#include <sys/types.h> - -#include <utils/Errors.h> -#include <utils/Log.h> -#include <binder/Parcel.h> - -#include <ui/BufferMapper.h> -#include <ui/Rect.h> -#include <private/ui/SurfaceBuffer.h> - -namespace android { - -// ============================================================================ -// SurfaceBuffer -// ============================================================================ - -SurfaceBuffer::SurfaceBuffer() - : BASE(), mOwner(false), mBufferMapper(BufferMapper::get()), mIndex(-1) -{ - width = - height = - stride = - format = - usage = 0; - handle = NULL; -} - -SurfaceBuffer::SurfaceBuffer(const Parcel& data) - : BASE(), mOwner(true), mBufferMapper(BufferMapper::get()) -{ - // we own the handle in this case - width = data.readInt32(); - if (width < 0) { - width = height = stride = format = usage = 0; - handle = 0; - } else { - height = data.readInt32(); - stride = data.readInt32(); - format = data.readInt32(); - usage = data.readInt32(); - handle = data.readNativeHandle(); - } -} - -SurfaceBuffer::~SurfaceBuffer() -{ - if (handle && mOwner) { - native_handle_close(handle); - native_handle_delete(const_cast<native_handle*>(handle)); - } -} - -status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr) -{ - const Rect lockBounds(width, height); - status_t res = lock(usage, lockBounds, vaddr); - return res; -} - -status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) -{ - if (rect.left < 0 || rect.right > this->width || - rect.top < 0 || rect.bottom > this->height) { - LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)", - rect.left, rect.top, rect.right, rect.bottom, - this->width, this->height); - return BAD_VALUE; - } - status_t res = getBufferMapper().lock(handle, usage, rect, vaddr); - return res; -} - -status_t SurfaceBuffer::unlock() -{ - status_t res = getBufferMapper().unlock(handle); - return res; -} - -status_t SurfaceBuffer::writeToParcel(Parcel* reply, - android_native_buffer_t const* buffer) -{ - if (buffer == NULL) - return BAD_VALUE; - - if (buffer->width < 0 || buffer->height < 0) - return BAD_VALUE; - - status_t err = NO_ERROR; - if (buffer->handle == NULL) { - // this buffer doesn't have a handle - reply->writeInt32(NO_MEMORY); - } else { - reply->writeInt32(buffer->width); - reply->writeInt32(buffer->height); - reply->writeInt32(buffer->stride); - reply->writeInt32(buffer->format); - reply->writeInt32(buffer->usage); - err = reply->writeNativeHandle(buffer->handle); - } - return err; -} - - -void SurfaceBuffer::setIndex(int index) { - mIndex = index; -} - -int SurfaceBuffer::getIndex() const { - return mIndex; -} - - -}; // namespace android - |