From 6950e428feaccc8164b989ef64e771a99948797a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 5 Oct 2009 17:07:12 -0700 Subject: 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. --- include/private/ui/SurfaceBuffer.h | 81 ---- include/private/ui/android_natives_priv.h | 47 +- include/ui/BufferMapper.h | 64 --- include/ui/GraphicBuffer.h | 124 +++++ include/ui/GraphicBufferAllocator.h | 96 ++++ include/ui/GraphicBufferMapper.h | 64 +++ include/ui/ISurface.h | 4 +- include/ui/Surface.h | 16 +- include/ui/android_native_buffer.h | 62 +++ libs/surfaceflinger/Android.mk | 2 - libs/surfaceflinger/Buffer.cpp | 137 ------ libs/surfaceflinger/Buffer.h | 83 ---- libs/surfaceflinger/BufferAllocator.cpp | 129 ------ libs/surfaceflinger/BufferAllocator.h | 96 ---- libs/surfaceflinger/Layer.cpp | 77 +++- libs/surfaceflinger/Layer.h | 16 +- libs/surfaceflinger/LayerBase.cpp | 95 ++-- libs/surfaceflinger/LayerBase.h | 19 +- libs/surfaceflinger/LayerBuffer.cpp | 11 +- libs/surfaceflinger/LayerBuffer.h | 5 +- libs/surfaceflinger/LayerDim.cpp | 10 +- libs/surfaceflinger/SurfaceFlinger.cpp | 11 +- libs/surfaceflinger/SurfaceFlinger.h | 3 +- libs/ui/Android.mk | 5 +- libs/ui/BufferMapper.cpp | 80 ---- libs/ui/GraphicBuffer.cpp | 213 +++++++++ libs/ui/GraphicBufferAllocator.cpp | 129 ++++++ libs/ui/GraphicBufferMapper.cpp | 80 ++++ libs/ui/ISurface.cpp | 10 +- libs/ui/Surface.cpp | 30 +- libs/ui/SurfaceBuffer.cpp | 134 ------ opengl/tests/copybits/Android.mk | 18 - opengl/tests/copybits/copybits.cpp | 726 ------------------------------ opengl/tests/gralloc/Android.mk | 4 +- opengl/tests/gralloc/Buffer.cpp | 111 ----- opengl/tests/gralloc/Buffer.h | 90 ---- opengl/tests/gralloc/BufferAllocator.cpp | 131 ------ opengl/tests/gralloc/BufferAllocator.h | 96 ---- opengl/tests/gralloc/gralloc.cpp | 8 +- 39 files changed, 941 insertions(+), 2176 deletions(-) delete mode 100644 include/private/ui/SurfaceBuffer.h delete mode 100644 include/ui/BufferMapper.h create mode 100644 include/ui/GraphicBuffer.h create mode 100644 include/ui/GraphicBufferAllocator.h create mode 100644 include/ui/GraphicBufferMapper.h create mode 100644 include/ui/android_native_buffer.h delete mode 100644 libs/surfaceflinger/Buffer.cpp delete mode 100644 libs/surfaceflinger/Buffer.h delete mode 100644 libs/surfaceflinger/BufferAllocator.cpp delete mode 100644 libs/surfaceflinger/BufferAllocator.h delete mode 100644 libs/ui/BufferMapper.cpp create mode 100644 libs/ui/GraphicBuffer.cpp create mode 100644 libs/ui/GraphicBufferAllocator.cpp create mode 100644 libs/ui/GraphicBufferMapper.cpp delete mode 100644 libs/ui/SurfaceBuffer.cpp delete mode 100644 opengl/tests/copybits/Android.mk delete mode 100644 opengl/tests/copybits/copybits.cpp delete mode 100644 opengl/tests/gralloc/Buffer.cpp delete mode 100644 opengl/tests/gralloc/Buffer.h delete mode 100644 opengl/tests/gralloc/BufferAllocator.cpp delete mode 100644 opengl/tests/gralloc/BufferAllocator.h diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h deleted file mode 100644 index 73e517b..0000000 --- a/include/private/ui/SurfaceBuffer.h +++ /dev/null @@ -1,81 +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_UI_PRIVATE_SURFACE_BUFFER_H -#define ANDROID_UI_PRIVATE_SURFACE_BUFFER_H - -#include -#include - -#include - -#include - -namespace android { - -// --------------------------------------------------------------------------- - -class BufferMapper; -class Parcel; -class Rect; -class Surface; -class SurfaceBuffer; - -// --------------------------------------------------------------------------- - -class SurfaceBuffer - : public EGLNativeBase< - android_native_buffer_t, - SurfaceBuffer, - LightRefBase > -{ -public: - status_t lock(uint32_t usage, void** vaddr); - status_t lock(uint32_t usage, const Rect& rect, void** vaddr); - status_t unlock(); - - void setIndex(int index); - int getIndex() const; - -protected: - SurfaceBuffer(); - SurfaceBuffer(const Parcel& reply); - virtual ~SurfaceBuffer(); - bool mOwner; - - inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } - inline BufferMapper& getBufferMapper() { return mBufferMapper; } - -private: - friend class Surface; - friend class BpSurface; - friend class BnSurface; - friend class LightRefBase; - - SurfaceBuffer& operator = (const SurfaceBuffer& rhs); - const SurfaceBuffer& operator = (const SurfaceBuffer& rhs) const; - - static status_t writeToParcel(Parcel* reply, - android_native_buffer_t const* buffer); - - BufferMapper& mBufferMapper; - int mIndex; -}; - -}; // namespace android - -#endif // ANDROID_UI_PRIVATE_SURFACE_BUFFER_H - diff --git a/include/private/ui/android_natives_priv.h b/include/private/ui/android_natives_priv.h index 9c92af8..6b9f524 100644 --- a/include/private/ui/android_natives_priv.h +++ b/include/private/ui/android_natives_priv.h @@ -14,49 +14,4 @@ * limitations under the License. */ -#ifndef ANDROID_ANDROID_NATIVES_PRIV_H -#define ANDROID_ANDROID_NATIVES_PRIV_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*****************************************************************************/ - -typedef struct android_native_buffer_t -{ -#ifdef __cplusplus - android_native_buffer_t() { - common.magic = ANDROID_NATIVE_BUFFER_MAGIC; - common.version = sizeof(android_native_buffer_t); - memset(common.reserved, 0, sizeof(common.reserved)); - } -#endif - - struct android_native_base_t common; - - int width; - int height; - int stride; - int format; - int usage; - - void* reserved[2]; - - buffer_handle_t handle; - - void* reserved_proc[8]; -} android_native_buffer_t; - - -/*****************************************************************************/ - -#ifdef __cplusplus -} -#endif - -/*****************************************************************************/ - -#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */ +#include diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h deleted file mode 100644 index 5f084be..0000000 --- a/include/ui/BufferMapper.h +++ /dev/null @@ -1,64 +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_UI_BUFFER_MAPPER_H -#define ANDROID_UI_BUFFER_MAPPER_H - -#include -#include - -#include - -#include - - -struct gralloc_module_t; - -namespace android { - -// --------------------------------------------------------------------------- - -class Rect; - -class BufferMapper : public Singleton -{ -public: - static inline BufferMapper& get() { return getInstance(); } - - status_t registerBuffer(buffer_handle_t handle); - - status_t unregisterBuffer(buffer_handle_t handle); - - status_t lock(buffer_handle_t handle, - int usage, const Rect& bounds, void** vaddr); - - status_t unlock(buffer_handle_t handle); - - // dumps information about the mapping of this handle - void dump(buffer_handle_t handle); - -private: - friend class Singleton; - BufferMapper(); - gralloc_module_t const *mAllocMod; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_UI_BUFFER_MAPPER_H - diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h new file mode 100644 index 0000000..8897f03 --- /dev/null +++ b/include/ui/GraphicBuffer.h @@ -0,0 +1,124 @@ +/* + * 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_GRAPHIC_BUFFER_H +#define ANDROID_GRAPHIC_BUFFER_H + +#include +#include + +#include +#include +#include +#include + +struct android_native_buffer_t; + +namespace android { + +class GraphicBufferMapper; +class Parcel; + +// =========================================================================== +// GraphicBuffer +// =========================================================================== + +class GraphicBuffer + : public EGLNativeBase< + android_native_buffer_t, + GraphicBuffer, + LightRefBase > +{ +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 + }; + + GraphicBuffer(); + + // creates w * h buffer + GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t ssage); + + // 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 reallocate(uint32_t w, uint32_t h, PixelFormat f, uint32_t usage); + + status_t lock(uint32_t usage, void** vaddr); + status_t lock(uint32_t usage, const Rect& rect, void** vaddr); + status_t lock(GGLSurface* surface, uint32_t usage); + status_t unlock(); + + android_native_buffer_t* getNativeBuffer() const; + + void setIndex(int index); + int getIndex() const; + +protected: + GraphicBuffer(const Parcel& reply); + virtual ~GraphicBuffer(); + + inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; } + inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; } + bool mOwner; + +private: + friend class Surface; + friend class BpSurface; + friend class BnSurface; + friend class LightRefBase; + GraphicBuffer(const GraphicBuffer& rhs); + GraphicBuffer& operator = (const GraphicBuffer& rhs); + const GraphicBuffer& operator = (const GraphicBuffer& rhs) const; + + status_t initSize(uint32_t w, uint32_t h, PixelFormat format, + uint32_t usage); + + static status_t writeToParcel(Parcel* reply, + android_native_buffer_t const* buffer); + + GraphicBufferMapper& mBufferMapper; + ssize_t mInitCheck; + uint32_t mVStride; + int mIndex; +}; + +}; // namespace android + +#endif // ANDROID_GRAPHIC_BUFFER_H diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h new file mode 100644 index 0000000..be9c79b --- /dev/null +++ b/include/ui/GraphicBufferAllocator.h @@ -0,0 +1,96 @@ +/* +** +** 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 + +#include + +#include +#include +#include +#include + +#include + +#include + + +namespace android { +// --------------------------------------------------------------------------- + +class String8; + +class GraphicBufferAllocator : public Singleton +{ +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 GraphicBufferAllocator& 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 sAllocList; + + friend class Singleton; + GraphicBufferAllocator(); + ~GraphicBufferAllocator(); + + mutable Mutex mLock; + alloc_device_t *mAllocDev; +}; + +// --------------------------------------------------------------------------- +}; // namespace android + +#endif // ANDROID_BUFFER_ALLOCATOR_H diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h new file mode 100644 index 0000000..697a02a --- /dev/null +++ b/include/ui/GraphicBufferMapper.h @@ -0,0 +1,64 @@ +/* + * 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_UI_BUFFER_MAPPER_H +#define ANDROID_UI_BUFFER_MAPPER_H + +#include +#include + +#include + +#include + + +struct gralloc_module_t; + +namespace android { + +// --------------------------------------------------------------------------- + +class Rect; + +class GraphicBufferMapper : public Singleton +{ +public: + static inline GraphicBufferMapper& get() { return getInstance(); } + + status_t registerBuffer(buffer_handle_t handle); + + status_t unregisterBuffer(buffer_handle_t handle); + + status_t lock(buffer_handle_t handle, + int usage, const Rect& bounds, void** vaddr); + + status_t unlock(buffer_handle_t handle); + + // dumps information about the mapping of this handle + void dump(buffer_handle_t handle); + +private: + friend class Singleton; + GraphicBufferMapper(); + gralloc_module_t const *mAllocMod; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_UI_BUFFER_MAPPER_H + diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h index 1283033..2ca0026 100644 --- a/include/ui/ISurface.h +++ b/include/ui/ISurface.h @@ -34,7 +34,7 @@ typedef int32_t SurfaceID; class IMemoryHeap; class OverlayRef; -class SurfaceBuffer; +class GraphicBuffer; class ISurface : public IInterface { @@ -50,7 +50,7 @@ protected: public: DECLARE_META_INTERFACE(Surface); - virtual sp requestBuffer(int bufferIdx, int usage) = 0; + virtual sp requestBuffer(int bufferIdx, int usage) = 0; class BufferHeap { public: diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 2cedeb6..70303cd 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -34,7 +34,7 @@ namespace android { // --------------------------------------------------------------------------- -class BufferMapper; +class GraphicBufferMapper; class IOMX; class Rect; class Surface; @@ -192,8 +192,8 @@ private: status_t validate(SharedClient const* cblk) const; - inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } - inline BufferMapper& getBufferMapper() { return mBufferMapper; } + inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; } + inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; } static int setSwapInterval(android_native_window_t* window, int interval); static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); @@ -208,7 +208,7 @@ private: int query(int what, int* value); int perform(int operation, va_list args); - status_t dequeueBuffer(sp* buffer); + status_t dequeueBuffer(sp* buffer); void setUsage(uint32_t reqUsage); @@ -221,7 +221,7 @@ private: uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; - BufferMapper& mBufferMapper; + GraphicBufferMapper& mBufferMapper; SharedBufferClient* mSharedBufferClient; // protected by mSurfaceLock @@ -230,12 +230,12 @@ private: // protected by mSurfaceLock. These are also used from lock/unlock // but in that case, they must be called form the same thread. - sp mBuffers[2]; + sp mBuffers[2]; mutable Region mDirtyRegion; // must be used from the lock/unlock thread - sp mLockedBuffer; - sp mPostedBuffer; + sp mLockedBuffer; + sp mPostedBuffer; mutable Region mOldDirtyRegion; bool mNeedFullUpdate; diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h new file mode 100644 index 0000000..9c92af8 --- /dev/null +++ b/include/ui/android_native_buffer.h @@ -0,0 +1,62 @@ +/* + * 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. + */ + +#ifndef ANDROID_ANDROID_NATIVES_PRIV_H +#define ANDROID_ANDROID_NATIVES_PRIV_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ + +typedef struct android_native_buffer_t +{ +#ifdef __cplusplus + android_native_buffer_t() { + common.magic = ANDROID_NATIVE_BUFFER_MAGIC; + common.version = sizeof(android_native_buffer_t); + memset(common.reserved, 0, sizeof(common.reserved)); + } +#endif + + struct android_native_base_t common; + + int width; + int height; + int stride; + int format; + int usage; + + void* reserved[2]; + + buffer_handle_t handle; + + void* reserved_proc[8]; +} android_native_buffer_t; + + +/*****************************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*****************************************************************************/ + +#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */ 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 -#include -#include - -#include -#include - -#include -#include - -#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(const_cast(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(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 -#include - -#include -#include -#include -#include - -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(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.cpp b/libs/surfaceflinger/BufferAllocator.cpp deleted file mode 100644 index 3e37bc3..0000000 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ /dev/null @@ -1,129 +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. -*/ - -#include - -#include -#include - -#include "BufferAllocator.h" - - -namespace android { -// --------------------------------------------------------------------------- - -ANDROID_SINGLETON_STATIC_INSTANCE( BufferAllocator ) - -Mutex BufferAllocator::sLock; -KeyedVector BufferAllocator::sAllocList; - -BufferAllocator::BufferAllocator() - : mAllocDev(0) -{ - hw_module_t const* module; - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); - if (err == 0) { - gralloc_open(module, &mAllocDev); - } -} - -BufferAllocator::~BufferAllocator() -{ - gralloc_close(mAllocDev); -} - -void BufferAllocator::dump(String8& result) const -{ - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - size_t total = 0; - const size_t SIZE = 512; - char buffer[SIZE]; - snprintf(buffer, SIZE, "Allocated buffers:\n"); - result.append(buffer); - const size_t c = list.size(); - for (size_t i=0 ; i0 ? c : 1; -} - -status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, - int usage, buffer_handle_t* handle, int32_t* stride) -{ - Mutex::Autolock _l(mLock); - - // make sure to not allocate a 0 x 0 buffer - w = clamp(w); - h = clamp(h); - - // we have a h/w allocator and h/w buffer is requested - status_t err = mAllocDev->alloc(mAllocDev, - w, h, format, usage, handle, stride); - - LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", - w, h, format, usage, err, strerror(-err)); - - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - alloc_rec_t rec; - rec.w = w; - rec.h = h; - rec.format = format; - rec.usage = usage; - rec.vaddr = 0; - rec.size = h * stride[0] * bytesPerPixel(format); - list.add(*handle, rec); - } else { - String8 s; - dump(s); - LOGD("%s", s.string()); - } - - return err; -} - -status_t BufferAllocator::free(buffer_handle_t handle) -{ - Mutex::Autolock _l(mLock); - - status_t err = mAllocDev->free(mAllocDev, handle); - LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); - - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - list.removeItem(handle); - } - - return err; -} - -// --------------------------------------------------------------------------- -}; // namespace android 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 - -#include - -#include -#include -#include -#include - -#include - -#include - - -namespace android { -// --------------------------------------------------------------------------- - -class String8; - -class BufferAllocator : public Singleton -{ -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 sAllocList; - - friend class Singleton; - 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 #include +#include #include #include -#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 buffer(getFrontBuffer()); - if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { + sp 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 ; ilock(&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 Layer::requestBuffer(int index, int usage) +sp Layer::requestBuffer(int index, int usage) { - sp buffer; + sp buffer; // this ensures our client doesn't go away while we're accessing // the shared area. @@ -269,14 +273,15 @@ sp 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 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 newFrontBuffer(getBuffer(buf)); + sp 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 Layer::SurfaceLayer::requestBuffer(int index, int usage) +sp Layer::SurfaceLayer::requestBuffer(int index, int usage) { - sp buffer; + sp buffer; sp 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 #include +#include #include #include @@ -28,7 +29,6 @@ #include #include -#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 getBuffer(int i) { return mBuffers[i]; } + inline sp getBuffer(int i) { return mBuffers[i]; } // only for debugging inline const sp& getFreezeLock() const { return mFreezeLock; } // only for debugging inline PixelFormat pixelFormat() const { return mFormat; } private: - inline sp getFrontBuffer() { + inline sp getFrontBuffer() { return mBuffers[mFrontBufferIndex]; } void reloadTexture(const Region& dirty); - sp requestBuffer(int index, int usage); + uint32_t getEffectiveUsage(uint32_t usage) const; + + sp requestBuffer(int index, int usage); void destroy(); class SurfaceLayer : public LayerBaseClient::Surface { @@ -96,7 +97,7 @@ private: SurfaceID id, const sp& owner); ~SurfaceLayer(); private: - virtual sp requestBuffer(int index, int usage); + virtual sp requestBuffer(int index, int usage); sp getOwner() const { return static_cast(Surface::getOwner().get()); } @@ -112,10 +113,9 @@ private: Region mPostedDirtyRegion; sp mFreezeLock; PixelFormat mFormat; - uint32_t mBufferFlags; // protected by mLock - sp mBuffers[NUM_BUFFERS]; + sp 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 LayerBaseClient::Surface::requestBuffer(int index, int usage) +sp 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 getOwner() const; private: - virtual sp requestBuffer(int index, int usage); + virtual sp 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 #include +#include #include #include #include -#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 #include -#include -#include - #include "LayerBase.h" struct copybit_device_t; @@ -133,7 +130,7 @@ private: status_t mStatus; ISurface::BufferHeap mBufferHeap; size_t mBufferSize; - mutable sp mTempBitmap; + mutable sp 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 #include -#include "Buffer.h" -#include "BufferAllocator.h" +#include + #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 = new Buffer(w, h, PIXEL_FORMAT_RGB_565, - BufferAllocator::USAGE_SW_WRITE_OFTEN | - BufferAllocator::USAGE_HW_TEXTURE); + sp 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 #include +#include #include #include @@ -44,8 +45,6 @@ #include #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& args) if (l != 0) { SharedBufferStack::Statistics stats = l->lcblk->getStats(); result.append( l->lcblk->dump(" ") ); - sp buf0(l->getBuffer(0)); - sp buf1(l->getBuffer(1)); + sp buf0(l->getBuffer(0)); + sp 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& 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/BufferMapper.cpp b/libs/ui/BufferMapper.cpp deleted file mode 100644 index 4add8f9..0000000 --- a/libs/ui/BufferMapper.cpp +++ /dev/null @@ -1,80 +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. - */ - -#define LOG_TAG "BufferMapper" - -#include -#include - -#include -#include - -#include -#include - -#include - - -namespace android { -// --------------------------------------------------------------------------- - -ANDROID_SINGLETON_STATIC_INSTANCE( BufferMapper ) - -BufferMapper::BufferMapper() - : mAllocMod(0) -{ - hw_module_t const* module; - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); - if (err == 0) { - mAllocMod = (gralloc_module_t const *)module; - } -} - -status_t BufferMapper::registerBuffer(buffer_handle_t handle) -{ - status_t err = mAllocMod->registerBuffer(mAllocMod, handle); - LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", - handle, err, strerror(-err)); - return err; -} - -status_t BufferMapper::unregisterBuffer(buffer_handle_t handle) -{ - status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle); - LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", - handle, err, strerror(-err)); - return err; -} - -status_t BufferMapper::lock(buffer_handle_t handle, - int usage, const Rect& bounds, void** vaddr) -{ - status_t err = mAllocMod->lock(mAllocMod, handle, usage, - bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); - LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); - return err; -} - -status_t BufferMapper::unlock(buffer_handle_t handle) -{ - status_t err = mAllocMod->unlock(mAllocMod, handle); - LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); - return err; -} - -// --------------------------------------------------------------------------- -}; // namespace android 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 +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include + +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(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( + const_cast(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(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/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp new file mode 100644 index 0000000..10b1051 --- /dev/null +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -0,0 +1,129 @@ +/* +** +** 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. +*/ + +#include + +#include +#include + +#include + + +namespace android { +// --------------------------------------------------------------------------- + +ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator ) + +Mutex GraphicBufferAllocator::sLock; +KeyedVector GraphicBufferAllocator::sAllocList; + +GraphicBufferAllocator::GraphicBufferAllocator() + : mAllocDev(0) +{ + hw_module_t const* module; + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + if (err == 0) { + gralloc_open(module, &mAllocDev); + } +} + +GraphicBufferAllocator::~GraphicBufferAllocator() +{ + gralloc_close(mAllocDev); +} + +void GraphicBufferAllocator::dump(String8& result) const +{ + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + size_t total = 0; + const size_t SIZE = 512; + char buffer[SIZE]; + snprintf(buffer, SIZE, "Allocated buffers:\n"); + result.append(buffer); + const size_t c = list.size(); + for (size_t i=0 ; i0 ? c : 1; +} + +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); + + // make sure to not allocate a 0 x 0 buffer + w = clamp(w); + h = clamp(h); + + // we have a h/w allocator and h/w buffer is requested + status_t err = mAllocDev->alloc(mAllocDev, + w, h, format, usage, handle, stride); + + LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", + w, h, format, usage, err, strerror(-err)); + + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + alloc_rec_t rec; + rec.w = w; + rec.h = h; + rec.format = format; + rec.usage = usage; + rec.vaddr = 0; + rec.size = h * stride[0] * bytesPerPixel(format); + list.add(*handle, rec); + } else { + String8 s; + dump(s); + LOGD("%s", s.string()); + } + + return err; +} + +status_t GraphicBufferAllocator::free(buffer_handle_t handle) +{ + Mutex::Autolock _l(mLock); + + status_t err = mAllocDev->free(mAllocDev, handle); + LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); + + if (err == NO_ERROR) { + Mutex::Autolock _l(sLock); + KeyedVector& list(sAllocList); + list.removeItem(handle); + } + + return err; +} + +// --------------------------------------------------------------------------- +}; // namespace android diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp new file mode 100644 index 0000000..dd529e6 --- /dev/null +++ b/libs/ui/GraphicBufferMapper.cpp @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#define LOG_TAG "GraphicBufferMapper" + +#include +#include + +#include +#include + +#include +#include + +#include + + +namespace android { +// --------------------------------------------------------------------------- + +ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper ) + +GraphicBufferMapper::GraphicBufferMapper() + : mAllocMod(0) +{ + hw_module_t const* module; + int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); + if (err == 0) { + mAllocMod = (gralloc_module_t const *)module; + } +} + +status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) +{ + status_t err = mAllocMod->registerBuffer(mAllocMod, handle); + LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); + return err; +} + +status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) +{ + status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle); + LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); + return err; +} + +status_t GraphicBufferMapper::lock(buffer_handle_t handle, + int usage, const Rect& bounds, void** vaddr) +{ + status_t err = mAllocMod->lock(mAllocMod, handle, usage, + bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); + LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); + return err; +} + +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)); + return err; +} + +// --------------------------------------------------------------------------- +}; // namespace android 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 #include -#include +#include namespace android { @@ -71,14 +71,14 @@ public: { } - virtual sp requestBuffer(int bufferIdx, int usage) + virtual sp 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 buffer = new SurfaceBuffer(reply); + sp 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 buffer(requestBuffer(bufferIdx, usage)); - return SurfaceBuffer::writeToParcel(reply, buffer.get()); + sp 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 #include -#include +#include +#include #include #include #include @@ -41,15 +42,14 @@ #include #include -#include namespace android { // ---------------------------------------------------------------------- static status_t copyBlt( - const sp& dst, - const sp& src, + const sp& dst, + const sp& src, const Region& reg) { status_t err; @@ -310,7 +310,7 @@ Surface::Surface(const sp& 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& surface) } Surface::Surface(const Parcel& parcel) - : mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL) + : mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL) { sp clientBinder = parcel.readStrongBinder(); mSurface = interface_cast(parcel.readStrongBinder()); @@ -473,11 +473,11 @@ int Surface::perform(android_native_window_t* window, // ---------------------------------------------------------------------------- -status_t Surface::dequeueBuffer(sp* buffer) { +status_t Surface::dequeueBuffer(sp* 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& backBuffer(mBuffers[bufIdx]); + const sp& 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 backBuffer; + sp 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& frontBuffer(mPostedBuffer); + const sp& 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& currentBuffer(mBuffers[index]); + sp& currentBuffer(mBuffers[index]); if (currentBuffer != 0) { getBufferMapper().unregisterBuffer(currentBuffer->handle); currentBuffer.clear(); } - sp buffer = s->requestBuffer(index, usage); + sp 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 -#include -#include - -#include -#include -#include - -#include -#include -#include - -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(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 - diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk deleted file mode 100644 index d5ded42..0000000 --- a/opengl/tests/copybits/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - copybits.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libEGL \ - libGLESv1_CM \ - libui - -LOCAL_MODULE:= test-opengl-copybits - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) - diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp deleted file mode 100644 index 11dfb6e..0000000 --- a/opengl/tests/copybits/copybits.cpp +++ /dev/null @@ -1,726 +0,0 @@ -// Test software OpenGL hardware accelleration using copybits. - -#define LOG_TAG "copybits_test" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include - -#include -#include - -#include -#include - -#define EGL_EGLEXT_PROTOTYPES -#define GL_GLEXT_PROTOTYPES - -#include -#include - -#include -#include - -using namespace android; - -EGLDisplay eglDisplay; -EGLSurface eglSurface; -EGLContext eglContext; -GLuint texture; - -hw_module_t const* gralloc_module; -alloc_device_t *sAllocDev; - -#define FIXED_ONE 0x10000 /* 1.0 in 16.16 fixed point. */ - -int init_gl_surface(); -void free_gl_surface(); -void init_scene(); - -int create_physical_texture(); -int readTimer(); - -// =========================================================================== -// Buffer an implementation of android_native_buffer_t -// =========================================================================== - -class NativeBuffer; - -class Buffer : public android::SurfaceBuffer -{ -public: - // creates w * h buffer - Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); - - // 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; } - - - android_native_buffer_t* getNativeBuffer() const; - - void setPixel(int x, int y, int r, int g, int b, int a); - - status_t lock(GGLSurface* surface, uint32_t usage); - void lock() { - GGLSurface s; - lock(&s, GRALLOC_USAGE_SW_WRITE_OFTEN); - mData = (void*)s.data; - } - -private: - friend class LightRefBase; - 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); - - ssize_t mInitCheck; - void* mData; -}; - -Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) - : SurfaceBuffer(), mInitCheck(NO_INIT) -{ - this->usage = usage; - this->format = format; - if (w>0 && h>0) { - mInitCheck = initSize(w, h); - } -} - -Buffer::~Buffer() -{ - if (handle) { - sAllocDev->free(sAllocDev, handle); - } -} - -status_t Buffer::initCheck() const { - return mInitCheck; -} - -android_native_buffer_t* Buffer::getNativeBuffer() const -{ - return static_cast(const_cast(this)); -} - -status_t Buffer::initSize(uint32_t w, uint32_t h) -{ - status_t err = NO_ERROR; - - err = sAllocDev->alloc(sAllocDev, w, h, format, usage, &handle, &stride); - - if (err == NO_ERROR) { - if (err == NO_ERROR) { - width = w; - height = h; - } - } - - 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->data = static_cast(vaddr); - } - return res; -} - - -void Buffer::setPixel(int x, int y, int r, int g, int b, int a) { - if (x < 0 || (unsigned int) x >= width - || y < 0 || (unsigned int) y >= height) { - // clipped - return; - } - int index = stride * y + x; - switch (format) { - case HAL_PIXEL_FORMAT_RGB_565: { - unsigned short val = (unsigned short) ( - ((0x1f & (r >> 3)) << 11) - | ((0x3f & (g >> 2)) << 5) - | (0x1f & (b >> 3))); - ((unsigned short*) mData)[index]= val; - } - break; - case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR - unsigned int val = (unsigned int) - (((a & 0xff) << 24) - | ((b & 0xff) << 16) - | ((g & 0xff) << 8) - | (r & 0xff)); - ((unsigned int*) mData)[index] = val; - } - break; - default: - // Unsupported pixel format - break; - } -} - - -static void gluLookAt(float eyeX, float eyeY, float eyeZ, - float centerX, float centerY, float centerZ, float upX, float upY, - float upZ) -{ - // See the OpenGL GLUT documentation for gluLookAt for a description - // of the algorithm. We implement it in a straightforward way: - - float fx = centerX - eyeX; - float fy = centerY - eyeY; - float fz = centerZ - eyeZ; - - // Normalize f - float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz); - fx *= rlf; - fy *= rlf; - fz *= rlf; - - // Normalize up - float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ); - upX *= rlup; - upY *= rlup; - upZ *= rlup; - - // compute s = f x up (x means "cross product") - - float sx = fy * upZ - fz * upY; - float sy = fz * upX - fx * upZ; - float sz = fx * upY - fy * upX; - - // compute u = s x f - float ux = sy * fz - sz * fy; - float uy = sz * fx - sx * fz; - float uz = sx * fy - sy * fx; - - float m[16] ; - m[0] = sx; - m[1] = ux; - m[2] = -fx; - m[3] = 0.0f; - - m[4] = sy; - m[5] = uy; - m[6] = -fy; - m[7] = 0.0f; - - m[8] = sz; - m[9] = uz; - m[10] = -fz; - m[11] = 0.0f; - - m[12] = 0.0f; - m[13] = 0.0f; - m[14] = 0.0f; - m[15] = 1.0f; - - glMultMatrixf(m); - glTranslatef(-eyeX, -eyeY, -eyeZ); -} - -int init_gralloc() { - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module); - LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); - - if (err == 0) { - gralloc_open(gralloc_module, &sAllocDev); - } - return err; -} - -int init_gl_surface(void) -{ - EGLint numConfigs = 1; - EGLConfig myConfig = {0}; - EGLint attrib[] = - { - EGL_DEPTH_SIZE, 16, - EGL_NONE - }; - - EGLNativeWindowType window = android_createDisplaySurface(); - - printf("init_gl_surface\n"); - if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY ) - { - printf("eglGetDisplay failed\n"); - return 0; - } - - if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE ) - { - printf("eglInitialize failed\n"); - return 0; - } - - if ( EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig) != 0) - { - printf("EGLUtils::selectConfigForNativeWindow failed\n"); - return 0; - } - - - if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig, - window, 0)) == EGL_NO_SURFACE ) - { - printf("eglCreateWindowSurface failed\n"); - return 0; - } - - if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT ) - { - printf("eglCreateContext failed\n"); - return 0; - } - - if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE ) - { - printf("eglMakeCurrent failed\n"); - return 0; - } - -#if EGL_ANDROID_swap_rectangle - eglSetSwapRectangleANDROID(eglDisplay, eglSurface, 0, 0, 320, 480); -#endif - - return 1; -} - -void free_gl_surface(void) -{ - if (eglDisplay != EGL_NO_DISPLAY) - { - eglMakeCurrent( eglDisplay, EGL_NO_SURFACE, - EGL_NO_SURFACE, EGL_NO_CONTEXT ); - eglDestroyContext( eglDisplay, eglContext ); - eglDestroySurface( eglDisplay, eglSurface ); - eglTerminate( eglDisplay ); - eglDisplay = EGL_NO_DISPLAY; - } -} - -void init_scene(void) -{ - glDisable(GL_DITHER); - glEnable(GL_CULL_FACE); - float ratio = 320.0f / 480.0f; - glViewport(0, 0, 320, 480); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustumf(-ratio, ratio, -1, 1, 1, 10); - - glMatrixMode(GL_MODELVIEW); - - glLoadIdentity(); - gluLookAt( - 0, 0, 3, // eye - 0, 0, 0, // center - 0, 1, 0); // up - - glEnable(GL_TEXTURE_2D); -} - -// #define USE_ALPHA_COLOR - -#define USE_GL_REPLACE -//#define USE_GL_MODULATE - -// #define USE_BLEND - -#define USE_565 -// #define USE_8888 - -// #define USE_NEAREST -#define USE_LINEAR - -#define USE_SCALE - -void setSmoothGradient(Buffer* bufferObject) { - int pixels = bufferObject->getHeight() * bufferObject->getWidth(); - int step = 0; - for (unsigned int y = 0; y < bufferObject->getHeight(); y++) { - for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) { - int grey = step * 255 / pixels; - bufferObject->setPixel(x, y, grey, grey, grey, 255); - ++step; - } - } -} - -void setSmoothAlphaGradient(Buffer* bufferObject) { - int pixels = bufferObject->getHeight() * bufferObject->getWidth(); - int step = 0; - for (unsigned int y = 0; y < bufferObject->getHeight(); y++) { - for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) { - int grey = step * 255 / pixels; - bufferObject->setPixel(x, y, 255, 255, 255, grey); - ++step; - } - } -} - -void setOrientedCheckerboard(Buffer* bufferObject) { - bufferObject->setPixel(0, 0, 0, 0, 0, 255); - for(unsigned int x = 1; x < bufferObject->getWidth() ; x++) { - bufferObject->setPixel(x, 0, 0, 255, 0, 255); - } - for (unsigned int y = 1; y < bufferObject->getHeight(); y++) { - for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) { - if ((x ^ y ) & 1) { - bufferObject->setPixel(x, y, 255, 255, 255, 255); - } else { - bufferObject->setPixel(x, y, 255, 0, 0, 255); - } - } - } -} - -int create_physical_texture(unsigned int w, unsigned int h) -{ - -#ifdef USE_565 - PixelFormat format = HAL_PIXEL_FORMAT_RGB_565; -#else - PixelFormat format = HAL_PIXEL_FORMAT_RGBA_8888; -#endif - int usage = GRALLOC_USAGE_SW_READ_OFTEN | - GRALLOC_USAGE_SW_WRITE_OFTEN | - GRALLOC_USAGE_HW_TEXTURE | - GRALLOC_USAGE_HW_2D; /* This is the key to allocating the texture in pmem. */ - int32_t stride; - buffer_handle_t handle; - - // Allocate the hardware buffer - Buffer* bufferObject = new Buffer(w, h, format, usage); - - android_native_buffer_t* buffer = bufferObject->getNativeBuffer(); - - buffer->common.incRef(&buffer->common); - - // create the new EGLImageKHR - EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_NONE }; - EGLDisplay dpy = eglGetCurrentDisplay(); - EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - (EGLClientBuffer)buffer, attrs); - if (image == EGL_NO_IMAGE_KHR) { - printf("Could not create an image %d\n", eglGetError()); - return -1; - } - - bufferObject->lock(); - setOrientedCheckerboard(bufferObject); - // setSmoothGradient(bufferObject); - // setSmoothAlphaGradient(bufferObject); - bufferObject->unlock(); - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); -#ifdef USE_LINEAR - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -#elif defined(USE_NEAREST) - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -#endif - -#ifdef USE_GL_REPLACE - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -#elif defined(USE_GL_MODULATE) - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -#endif - -#ifdef USE_ALPHA_COLOR - glColor4f(1.0f, 1.0f, 1.0f, 0.4f); -#else - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); -#endif - -#ifdef USE_BLEND - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#endif - return 0; -} - -static const int SCALE_COUNT = 12; - -int scale(int base, int factor) { - static const float kTable[SCALE_COUNT] = { - 0.24f, 0.25f, 0.5f, 0.75f, 1.0f, - 1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f - }; - return base * kTable[factor]; -} - -class Timer { - struct timeval first; - double elapsedSeconds; - -public: - Timer() {} - void start() { - gettimeofday(&first, NULL); - } - - void stop() { - struct timeval second, - elapsed; - gettimeofday(&second, NULL); - - if (first.tv_usec > second.tv_usec) { - second.tv_usec += 1000000; - second.tv_sec--; - } - - elapsedSeconds = (second.tv_sec - first.tv_sec) + - (second.tv_usec - first.tv_usec) / 1000000.0; - } - - double getElapsedSeconds() { - return elapsedSeconds; - } - - double getElapsedMs() { - return elapsedSeconds* 1000.0f; - } -}; - -int testTime() -{ - static const int WIDTH = 320; - static const int HEIGHT = 480; - static const int SCALE = 8; - - if (create_physical_texture(WIDTH, HEIGHT) != 0) { - return -1; - } - // Need to do a dummy eglSwapBuffers first. Don't know why. - glClearColor(0.4, 1.0, 0.4, 0.4); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - eglSwapBuffers(eglDisplay, eglSurface); - - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - -#if defined(USE_SCALE) - static const int scaleOffset = 0; -#else - static const int scaleOffset = 1; -#endif - printf("ms\n"); - for(int j = 0; j < SCALE; j++) { - int w = WIDTH >> (j + scaleOffset); - int h = HEIGHT >> j; - int cropRect[4] = {0,h,w,-h}; // Left bottom width height. Width and Height can be neg to flip. - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - Timer timer; - timer.start(); - - int copyCount = 1000; - for (int i = 0; i < copyCount; i++) { - glDrawTexiOES(0, 0, 0, w, h); - } - - timer.stop(); - printf("%g\n", timer.getElapsedMs() / copyCount); - } - - eglSwapBuffers(eglDisplay, eglSurface); - return 0; -} - -int testStretch() -{ - static const int WIDTH = 8; - static const int HEIGHT = 8; - - if (create_physical_texture(WIDTH, HEIGHT) != 0) { - return -1; - } - // Need to do a dummy eglSwapBuffers first. Don't know why. - glClearColor(0.4, 1.0, 0.4, 1.0); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - eglSwapBuffers(eglDisplay, eglSurface); - - int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip. - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - - for(int frame = 0; frame < 2; frame++) { - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - int baseX = 10; - for (int x = 0; x < SCALE_COUNT; x++) { - int baseY = 10; - int width = scale(WIDTH, x); - for (int y = 0; y < SCALE_COUNT; y++) { - int height = scale(HEIGHT, y); - glDrawTexxOES(baseX << 16, baseY << 16, 0, width << 16, height << 16); - baseY += height + 10; - } - baseX += width + 10; - } - - eglSwapBuffers(eglDisplay, eglSurface); - LOGD("wait 1s"); - usleep(1000000); - } - return 0; -} - -int testRot90() -{ - static const int WIDTH = 8; - static const int HEIGHT = 8; - - if (create_physical_texture(WIDTH, HEIGHT) != 0) { - return -1; - } - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof(0, 320, 480, 0, 0, 1); - - glMatrixMode(GL_MODELVIEW); - - glLoadIdentity(); - - // Need to do a dummy eglSwapBuffers first. Don't know why. - glClearColor(0.4, 0.4, 0.4, 0.4); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - eglSwapBuffers(eglDisplay, eglSurface); - - glEnable(GL_TEXTURE_2D); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glColor4x(0x10000, 0x10000, 0x10000, 0x10000); - glDisable(GL_BLEND); - glShadeModel(GL_FLAT); - glDisable(GL_DITHER); - glDisable(GL_CULL_FACE); - - for(int frame = 0; frame < 2; frame++) { - LOGD("frame = %d", frame); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - int baseX = 10; - for (int x = 0; x < SCALE_COUNT; x++) { - int baseY = 10; - int width = scale(WIDTH, x); - for (int y = 0; y < SCALE_COUNT; y++) { - int height = scale(HEIGHT, y); - - // Code copied from SurfaceFlinger LayerBase.cpp - - const GLfixed texCoords[4][2] = { - { 0, 0 }, - { 0, 0x10000 }, - { 0x10000, 0x10000 }, - { 0x10000, 0 } - }; - - GLfixed fx = baseX << 16; - GLfixed fy = baseY << 16; - GLfixed fw = width << 16; - GLfixed fh = height << 16; - - /* - * Vertex pattern: - * (2)--(3) - * |\ | - * | \ | - * | \ | - * | \| - * (1)--(0) - * - */ - - const GLfixed vertices[4][2] = { - {fx + fw, fy}, - {fx, fy}, - {fx, fy + fh}, - {fx + fw, fy + fh} - }; - - static const bool rotate90 = true; - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FIXED, 0, vertices); - glTexCoordPointer(2, GL_FIXED, 0, texCoords); - - LOGD("testRot90 %d, %d %d, %d", baseX, baseY, width, height); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - baseY += height + 10; - } - baseX += width + 10; - } - - eglSwapBuffers(eglDisplay, eglSurface); - } - return 0; -} - -int main(int argc, char **argv) -{ - - int q; - int start, end; - - if (init_gralloc()) { - printf("gralloc initialization failed - exiting\n"); - return 0; - } - - printf("Initializing EGL...\n"); - - if(!init_gl_surface()) - { - printf("GL initialisation failed - exiting\n"); - return 0; - } - - init_scene(); - - printf("Start test...\n"); - // testTime(); - testStretch(); - //testRot90(); - free_gl_surface(); - - return 0; -} diff --git a/opengl/tests/gralloc/Android.mk b/opengl/tests/gralloc/Android.mk index a86c8ec..d43c39a 100644 --- a/opengl/tests/gralloc/Android.mk +++ b/opengl/tests/gralloc/Android.mk @@ -2,9 +2,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - gralloc.cpp \ - Buffer.cpp \ - BufferAllocator.cpp + gralloc.cpp LOCAL_SHARED_LIBRARIES := \ libcutils \ diff --git a/opengl/tests/gralloc/Buffer.cpp b/opengl/tests/gralloc/Buffer.cpp deleted file mode 100644 index 3920ff0..0000000 --- a/opengl/tests/gralloc/Buffer.cpp +++ /dev/null @@ -1,111 +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 -#include -#include - -#include -#include - -#include -#include - -#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(const_cast(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(); - err = allocator.alloc(w, h, format, reqUsage, &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(vaddr); - } - return res; -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/opengl/tests/gralloc/Buffer.h b/opengl/tests/gralloc/Buffer.h deleted file mode 100644 index 8a32153..0000000 --- a/opengl/tests/gralloc/Buffer.h +++ /dev/null @@ -1,90 +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 -#include - -#include - -#include - -#include -#include -#include - -#include - -struct android_native_buffer_t; - -namespace android { - -// =========================================================================== -// Buffer -// =========================================================================== - -class NativeBuffer; - -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(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/opengl/tests/gralloc/BufferAllocator.cpp b/opengl/tests/gralloc/BufferAllocator.cpp deleted file mode 100644 index caf9bec..0000000 --- a/opengl/tests/gralloc/BufferAllocator.cpp +++ /dev/null @@ -1,131 +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. -*/ - -#include -#include -#include - -#include -#include - -#include "BufferAllocator.h" - - -namespace android { -// --------------------------------------------------------------------------- - -ANDROID_SINGLETON_STATIC_INSTANCE( BufferAllocator ) - -Mutex BufferAllocator::sLock; -KeyedVector BufferAllocator::sAllocList; - -BufferAllocator::BufferAllocator() - : mAllocDev(0) -{ - hw_module_t const* module; - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); - if (err == 0) { - gralloc_open(module, &mAllocDev); - } -} - -BufferAllocator::~BufferAllocator() -{ - gralloc_close(mAllocDev); -} - -void BufferAllocator::dump(String8& result) const -{ - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - size_t total = 0; - const size_t SIZE = 512; - char buffer[SIZE]; - snprintf(buffer, SIZE, "Allocated buffers:\n"); - result.append(buffer); - const size_t c = list.size(); - for (size_t i=0 ; i0 ? c : 1; -} - -status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, - int usage, buffer_handle_t* handle, int32_t* stride) -{ - Mutex::Autolock _l(mLock); - - // make sure to not allocate a 0 x 0 buffer - w = clamp(w); - h = clamp(h); - - // we have a h/w allocator and h/w buffer is requested - status_t err = mAllocDev->alloc(mAllocDev, - w, h, format, usage, handle, stride); - - LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", - w, h, format, usage, err, strerror(-err)); - - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - alloc_rec_t rec; - rec.w = w; - rec.h = h; - rec.format = format; - rec.usage = usage; - rec.vaddr = 0; - rec.size = h * stride[0] * bytesPerPixel(format); - list.add(*handle, rec); - } else { - String8 s; - dump(s); - LOGD("%s", s.string()); - } - - return err; -} - -status_t BufferAllocator::free(buffer_handle_t handle) -{ - Mutex::Autolock _l(mLock); - - status_t err = mAllocDev->free(mAllocDev, handle); - LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); - - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - list.removeItem(handle); - } - - return err; -} - -// --------------------------------------------------------------------------- -}; // namespace android diff --git a/opengl/tests/gralloc/BufferAllocator.h b/opengl/tests/gralloc/BufferAllocator.h deleted file mode 100644 index a279ded..0000000 --- a/opengl/tests/gralloc/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 - -#include - -#include -#include -#include -#include - -#include - -#include - - -namespace android { -// --------------------------------------------------------------------------- - -class String8; - -class BufferAllocator : public Singleton -{ -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 sAllocList; - - friend class Singleton; - BufferAllocator(); - ~BufferAllocator(); - - mutable Mutex mLock; - alloc_device_t *mAllocDev; -}; - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_BUFFER_ALLOCATOR_H diff --git a/opengl/tests/gralloc/gralloc.cpp b/opengl/tests/gralloc/gralloc.cpp index d989bb2..8987040 100644 --- a/opengl/tests/gralloc/gralloc.cpp +++ b/opengl/tests/gralloc/gralloc.cpp @@ -22,8 +22,8 @@ #include #include -#include "Buffer.h" -#include +#include +#include using namespace android; @@ -46,7 +46,7 @@ int main(int argc, char** argv) memset(temp2, 0, size); - sp buffer = new Buffer(128, 256, HAL_PIXEL_FORMAT_RGBA_8888, + sp buffer = new GraphicBuffer(128, 256, HAL_PIXEL_FORMAT_RGBA_8888, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); @@ -57,7 +57,7 @@ int main(int argc, char** argv) } void* vaddr; - buffer->SurfaceBuffer::lock( + buffer->lock( GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr); -- cgit v1.1 From 6f5f5a095a5a4d42fc656cf8c1e6d0f67594f88d Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 5 Oct 2009 18:19:57 -0700 Subject: fix [2168531] have software-only gralloc buffer side-step the HAL --- include/private/ui/sw_gralloc_handle.h | 83 +++++++++++++++++ libs/ui/GraphicBufferAllocator.cpp | 22 +++-- libs/ui/GraphicBufferMapper.cpp | 158 +++++++++++++++++++++++++++++++-- 3 files changed, 253 insertions(+), 10 deletions(-) create mode 100644 include/private/ui/sw_gralloc_handle.h diff --git a/include/private/ui/sw_gralloc_handle.h b/include/private/ui/sw_gralloc_handle.h new file mode 100644 index 0000000..b3d333e --- /dev/null +++ b/include/private/ui/sw_gralloc_handle.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 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_UI_PRIVATE_SW_GRALLOC_HANDLE_H +#define ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H + +#include +#include +#include +#include +#include + +#include + +namespace android { + +/*****************************************************************************/ + +struct sw_gralloc_handle_t : public native_handle +{ + // file-descriptors + int fd; + // ints + int magic; + int size; + int base; + int prot; + int pid; + + static const int sNumInts = 5; + static const int sNumFds = 1; + static const int sMagic = '_sgh'; + + sw_gralloc_handle_t() : + fd(-1), magic(sMagic), size(0), base(0), prot(0), pid(getpid()) + { + version = sizeof(native_handle); + numInts = sNumInts; + numFds = sNumFds; + } + ~sw_gralloc_handle_t() { + magic = 0; + } + + static int validate(const native_handle* h) { + const sw_gralloc_handle_t* hnd = (const sw_gralloc_handle_t*)h; + if (!h || h->version != sizeof(native_handle) || + h->numInts != sNumInts || h->numFds != sNumFds || + hnd->magic != sMagic) + { + return -EINVAL; + } + return 0; + } + + static status_t alloc(uint32_t w, uint32_t h, int format, + int usage, buffer_handle_t* handle, int32_t* stride); + static status_t free(sw_gralloc_handle_t* hnd); + static status_t registerBuffer(sw_gralloc_handle_t* hnd); + static status_t unregisterBuffer(sw_gralloc_handle_t* hnd); + static status_t lock(sw_gralloc_handle_t* hnd, int usage, + int l, int t, int w, int h, void** vaddr); + static status_t unlock(sw_gralloc_handle_t* hnd); +}; + +/*****************************************************************************/ + +}; // namespace android + +#endif /* ANDROID_UI_PRIVATE_SW_GRALLOC_HANDLE_H */ diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index 10b1051..57d5fc3 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -22,6 +22,7 @@ #include +#include namespace android { // --------------------------------------------------------------------------- @@ -29,7 +30,8 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator ) Mutex GraphicBufferAllocator::sLock; -KeyedVector GraphicBufferAllocator::sAllocList; +KeyedVector GraphicBufferAllocator::sAllocList; GraphicBufferAllocator::GraphicBufferAllocator() : mAllocDev(0) @@ -83,8 +85,13 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma h = clamp(h); // we have a h/w allocator and h/w buffer is requested - status_t err = mAllocDev->alloc(mAllocDev, - w, h, format, usage, handle, stride); + status_t err; + + if (usage & GRALLOC_USAGE_HW_MASK) { + err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride); + } else { + err = sw_gralloc_handle_t::alloc(w, h, format, usage, handle, stride); + } LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", w, h, format, usage, err, strerror(-err)); @@ -113,9 +120,14 @@ status_t GraphicBufferAllocator::free(buffer_handle_t handle) { Mutex::Autolock _l(mLock); - status_t err = mAllocDev->free(mAllocDev, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocDev->free(mAllocDev, handle); + } else { + err = sw_gralloc_handle_t::free((sw_gralloc_handle_t*)handle); + } + LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); - if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp index dd529e6..ce2acd0 100644 --- a/libs/ui/GraphicBufferMapper.cpp +++ b/libs/ui/GraphicBufferMapper.cpp @@ -17,7 +17,15 @@ #define LOG_TAG "GraphicBufferMapper" #include +#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define +# include +#else +# include +#endif #include +#include + +#include #include #include @@ -27,6 +35,8 @@ #include +#include + namespace android { // --------------------------------------------------------------------------- @@ -46,7 +56,12 @@ GraphicBufferMapper::GraphicBufferMapper() status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) { - status_t err = mAllocMod->registerBuffer(mAllocMod, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->registerBuffer(mAllocMod, handle); + } else { + err = sw_gralloc_handle_t::registerBuffer((sw_gralloc_handle_t*)handle); + } LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", handle, err, strerror(-err)); return err; @@ -54,7 +69,12 @@ status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle) status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle) { - status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->unregisterBuffer(mAllocMod, handle); + } else { + err = sw_gralloc_handle_t::unregisterBuffer((sw_gralloc_handle_t*)handle); + } LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)", handle, err, strerror(-err)); return err; @@ -63,18 +83,146 @@ status_t GraphicBufferMapper::unregisterBuffer(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, - bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->lock(mAllocMod, handle, usage, + bounds.left, bounds.top, bounds.width(), bounds.height(), + vaddr); + } else { + err = sw_gralloc_handle_t::lock((sw_gralloc_handle_t*)handle, usage, + bounds.left, bounds.top, bounds.width(), bounds.height(), + vaddr); + } LOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err)); return err; } status_t GraphicBufferMapper::unlock(buffer_handle_t handle) { - status_t err = mAllocMod->unlock(mAllocMod, handle); + status_t err; + if (sw_gralloc_handle_t::validate(handle) < 0) { + err = mAllocMod->unlock(mAllocMod, handle); + } else { + err = sw_gralloc_handle_t::unlock((sw_gralloc_handle_t*)handle); + } LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); return err; } // --------------------------------------------------------------------------- + +status_t sw_gralloc_handle_t::alloc(uint32_t w, uint32_t h, int format, + int usage, buffer_handle_t* pHandle, int32_t* pStride) +{ + int align = 4; + int bpp = 0; + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + bpp = 4; + break; + case HAL_PIXEL_FORMAT_RGB_888: + bpp = 3; + break; + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + break; + default: + return -EINVAL; + } + size_t bpr = (w*bpp + (align-1)) & ~(align-1); + size_t size = bpr * h; + size_t stride = bpr / bpp; + size = (size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); + + int fd = ashmem_create_region("sw-gralloc-buffer", size); + if (fd < 0) { + LOGE("ashmem_create_region(size=%d) failed (%s)", + size, strerror(-errno)); + return -errno; + } + + int prot = PROT_READ; + if (usage & GRALLOC_USAGE_SW_WRITE_MASK) + prot |= PROT_WRITE; + + if (ashmem_set_prot_region(fd, prot) < 0) { + LOGE("ashmem_set_prot_region(fd=%d, prot=%x) failed (%s)", + fd, prot, strerror(-errno)); + close(fd); + return -errno; + } + + void* base = mmap(0, size, prot, MAP_SHARED, fd, 0); + if (base == MAP_FAILED) { + LOGE("alloc mmap(fd=%d, size=%d, prot=%x) failed (%s)", + fd, size, prot, strerror(-errno)); + close(fd); + return -errno; + } + + sw_gralloc_handle_t* hnd = new sw_gralloc_handle_t(); + hnd->fd = fd; + hnd->size = size; + hnd->base = intptr_t(base); + hnd->prot = prot; + *pStride = stride; + *pHandle = hnd; + + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::free(sw_gralloc_handle_t* hnd) +{ + if (hnd->base) { + munmap((void*)hnd->base, hnd->size); + } + if (hnd->fd >= 0) { + close(hnd->fd); + } + delete hnd; + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::registerBuffer(sw_gralloc_handle_t* hnd) +{ + if (hnd->pid != getpid()) { + void* base = mmap(0, hnd->size, hnd->prot, MAP_SHARED, hnd->fd, 0); + if (base == MAP_FAILED) { + LOGE("registerBuffer mmap(fd=%d, size=%d, prot=%x) failed (%s)", + hnd->fd, hnd->size, hnd->prot, strerror(-errno)); + return -errno; + } + hnd->base = intptr_t(base); + } + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::unregisterBuffer(sw_gralloc_handle_t* hnd) +{ + if (hnd->pid != getpid()) { + if (hnd->base) { + munmap((void*)hnd->base, hnd->size); + } + hnd->base = 0; + } + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::lock(sw_gralloc_handle_t* hnd, int usage, + int l, int t, int w, int h, void** vaddr) +{ + *vaddr = (void*)hnd->base; + return NO_ERROR; +} + +status_t sw_gralloc_handle_t::unlock(sw_gralloc_handle_t* hnd) +{ + return NO_ERROR; +} + +// --------------------------------------------------------------------------- }; // namespace android -- cgit v1.1 From 351a7073fb60eb3534ec8c69ab263f057a124500 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 5 Oct 2009 18:20:39 -0700 Subject: fix [2168528] enable glTexImage2D code path in SF for software-only buffers --- libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 9 +++++++-- libs/surfaceflinger/DisplayHardware/DisplayHardware.h | 1 + libs/surfaceflinger/Layer.cpp | 17 ++++++++++++++--- libs/surfaceflinger/Layer.h | 1 + 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 8a7abec..f84933e 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -123,7 +123,7 @@ void DisplayHardware::init(uint32_t dpy) EGLint numConfigs=0; EGLSurface surface; EGLContext context; - mFlags = 0; + mFlags = CACHED_BUFFERS; // TODO: all the extensions below should be queried through // eglGetProcAddress(). @@ -239,12 +239,17 @@ void DisplayHardware::init(uint32_t dpy) eglMakeCurrent(display, surface, surface, context); const char* const gl_extensions = (const char*)glGetString(GL_EXTENSIONS); + const char* const gl_renderer = (const char*)glGetString(GL_RENDERER); LOGI("OpenGL informations:"); LOGI("vendor : %s", glGetString(GL_VENDOR)); - LOGI("renderer : %s", glGetString(GL_RENDERER)); + LOGI("renderer : %s", gl_renderer); LOGI("version : %s", glGetString(GL_VERSION)); LOGI("extensions: %s", gl_extensions); + if (strstr(gl_renderer, "PowerVR SGX 530")) { + LOGD("Assuming uncached graphics buffers."); + mFlags &= ~CACHED_BUFFERS; + } if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) { mFlags |= NPOT_EXTENSION; } diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h index cb688b7..6914d0c 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h @@ -51,6 +51,7 @@ public: PARTIAL_UPDATES = 0x00020000, // video driver feature SLOW_CONFIG = 0x00040000, // software SWAP_RECTANGLE = 0x00080000, + CACHED_BUFFERS = 0x00100000 }; DisplayHardware( diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index c1f7f27..eb0614f 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -51,6 +51,7 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp& c, int32_t i) : LayerBaseClient(flinger, display, c, i), mSecure(false), + mNoEGLImageForSwBuffers(false), mNeedsBlending(true), mNeedsDithering(false) { @@ -108,13 +109,15 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, const DisplayHardware& hw(graphicPlane(0).displayHardware()); PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(), &displayInfo); - + const uint32_t hwFlags = hw.getFlags(); + mFormat = format; mWidth = w; mHeight = h; mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; - + mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS); + // we use the red index int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); @@ -331,7 +334,15 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const } else { // it's allowed to modify the usage flags here, but generally // the requested flags should be honored. - usage |= GraphicBuffer::USAGE_HW_TEXTURE; + if (mNoEGLImageForSwBuffers) { + if (usage & GraphicBuffer::USAGE_HW_MASK) { + // request EGLImage for h/w buffers only + usage |= GraphicBuffer::USAGE_HW_TEXTURE; + } + } else { + // request EGLImage for all buffers + usage |= GraphicBuffer::USAGE_HW_TEXTURE; + } } return usage; } diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index e176cfc..6f59241 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -107,6 +107,7 @@ private: sp mSurface; bool mSecure; + bool mNoEGLImageForSwBuffers; int32_t mFrontBufferIndex; bool mNeedsBlending; bool mNeedsDithering; -- cgit v1.1