From 1473f46cbc82aa6f0ba744cc896a36923823d55b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 10 Apr 2009 14:24:30 -0700 Subject: Integrate from //sandbox/mathias/donut/...@145728 SurfaceFlinger rework for new EGL driver model support. --- opengl/libagl/TextureObjectManager.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'opengl/libagl/TextureObjectManager.cpp') diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index ce31854172d3..f927de95ecae 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -1,16 +1,16 @@ /* ** Copyright 2006, 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 + ** 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 + ** 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 + ** 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. */ @@ -53,6 +53,9 @@ void EGLTextureObject::init() memset(crop_rect, 0, sizeof(crop_rect)); generate_mipmap = GL_FALSE; direct = GL_FALSE; +#ifdef LIBAGL_USE_GRALLOC_COPYBITS + copybits_fd = -1; +#endif // LIBAGL_USE_GRALLOC_COPYBITS } void EGLTextureObject::copyParameters(const sp& old) @@ -146,7 +149,7 @@ status_t EGLTextureObject::reallocate( int format, int compressedFormat, int bpr) { const size_t size = h * bpr; - if (level == 0) + if (level == 0) { if (size!=mSize || !surface.data) { if (mSize && surface.data) { @@ -177,9 +180,9 @@ status_t EGLTextureObject::reallocate( return NO_MEMORY; } - LOGW_IF(level-1 >= mNumExtraLod, + LOGW_IF(level-1 >= mNumExtraLod, "specifying mipmap level %d, but # of level is %d", - level, mNumExtraLod+1); + level, mNumExtraLod+1); GGLSurface& mipmap = editMip(level); if (mipmap.data) -- cgit v1.2.3-59-g8ed1b From dff8e58d47ede6e748c0b02e128ca33b42a4f362 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 4 May 2009 14:17:04 -0700 Subject: update surfaceflinger, libui and libagl to the new gralloc api - Currently the lock/unlock path is naive and is done for each drawing operation (glDrawElements and glDrawArrays). this should be improved eventually. - factor all the lock/unlock code in SurfaceBuffer. - fixed "showupdate" so it works even when we don't have preserving eglSwapBuffers(). - improved the situation with the dirty-region and fixed a problem that caused GL apps to not update. - make use of LightRefBase() where needed, instead of duplicating its implementation - add LightRefBase::getStrongCount() - renamed EGLNativeWindowSurface.cpp to FramebufferNativeWindow.cpp - disabled copybits test, since it clashes with the new gralloc api - Camera/Video will be fixed later when we rework the overlay apis --- include/ui/BufferMapper.h | 23 +- include/ui/EGLDisplaySurface.h | 86 ------- include/ui/EGLNativeWindowSurface.h | 125 ---------- include/ui/FramebufferNativeWindow.h | 111 +++++++++ include/ui/Region.h | 1 + include/ui/Surface.h | 39 +-- include/utils/RefBase.h | 4 + libs/surfaceflinger/Android.mk | 3 - libs/surfaceflinger/BootAnimation.cpp | 2 +- libs/surfaceflinger/BufferAllocator.cpp | 56 +---- libs/surfaceflinger/BufferAllocator.h | 4 - .../DisplayHardware/DisplayHardware.cpp | 5 +- libs/surfaceflinger/Layer.cpp | 15 +- libs/surfaceflinger/LayerBase.cpp | 24 +- libs/surfaceflinger/LayerBase.h | 3 +- libs/surfaceflinger/LayerBitmap.cpp | 43 ++-- libs/surfaceflinger/LayerBitmap.h | 5 +- libs/surfaceflinger/LayerBuffer.cpp | 38 +-- libs/surfaceflinger/LayerOrientationAnim.cpp | 272 --------------------- libs/surfaceflinger/LayerOrientationAnim.h | 112 --------- libs/surfaceflinger/LayerOrientationAnimRotate.cpp | 269 -------------------- libs/surfaceflinger/LayerOrientationAnimRotate.h | 77 ------ libs/surfaceflinger/OrientationAnimation.cpp | 150 ------------ libs/surfaceflinger/OrientationAnimation.h | 84 ------- libs/surfaceflinger/SurfaceFlinger.cpp | 41 ++-- libs/surfaceflinger/SurfaceFlinger.h | 4 - .../purgatory/LayerOrientationAnim.cpp | 272 +++++++++++++++++++++ .../purgatory/LayerOrientationAnim.h | 112 +++++++++ .../purgatory/LayerOrientationAnimRotate.cpp | 269 ++++++++++++++++++++ .../purgatory/LayerOrientationAnimRotate.h | 77 ++++++ .../purgatory/OrientationAnimation.cpp | 150 ++++++++++++ .../purgatory/OrientationAnimation.h | 84 +++++++ libs/ui/Android.mk | 2 +- libs/ui/BufferMapper.cpp | 100 +------- libs/ui/EGLNativeWindowSurface.cpp | 244 ------------------ libs/ui/FramebufferNativeWindow.cpp | 214 ++++++++++++++++ libs/ui/Region.cpp | 7 + libs/ui/Surface.cpp | 225 ++++++++--------- opengl/include/EGL/android_natives.h | 26 +- opengl/libagl/TextureObjectManager.cpp | 20 +- opengl/libagl/TextureObjectManager.h | 50 +--- opengl/libagl/array.cpp | 17 ++ opengl/libagl/egl.cpp | 71 +++--- opengl/libagl/texture.cpp | 88 +++++-- opengl/libagl/texture.h | 10 +- opengl/tests/copybits/Android.mk | 2 +- 46 files changed, 1709 insertions(+), 1927 deletions(-) delete mode 100644 include/ui/EGLDisplaySurface.h delete mode 100644 include/ui/EGLNativeWindowSurface.h create mode 100644 include/ui/FramebufferNativeWindow.h delete mode 100644 libs/surfaceflinger/LayerOrientationAnim.cpp delete mode 100644 libs/surfaceflinger/LayerOrientationAnim.h delete mode 100644 libs/surfaceflinger/LayerOrientationAnimRotate.cpp delete mode 100644 libs/surfaceflinger/LayerOrientationAnimRotate.h delete mode 100644 libs/surfaceflinger/OrientationAnimation.cpp delete mode 100644 libs/surfaceflinger/OrientationAnimation.h create mode 100644 libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp create mode 100644 libs/surfaceflinger/purgatory/LayerOrientationAnim.h create mode 100644 libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp create mode 100644 libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h create mode 100644 libs/surfaceflinger/purgatory/OrientationAnimation.cpp create mode 100644 libs/surfaceflinger/purgatory/OrientationAnimation.h delete mode 100644 libs/ui/EGLNativeWindowSurface.cpp create mode 100644 libs/ui/FramebufferNativeWindow.cpp (limited to 'opengl/libagl/TextureObjectManager.cpp') diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h index ff9003300296..5f084becf943 100644 --- a/include/ui/BufferMapper.h +++ b/include/ui/BufferMapper.h @@ -20,10 +20,7 @@ #include #include -#include -#include #include -#include #include @@ -40,9 +37,14 @@ class BufferMapper : public Singleton { public: static inline BufferMapper& get() { return getInstance(); } - status_t map(buffer_handle_t handle, void** addr, const void* id); - status_t unmap(buffer_handle_t handle, const void* id); - status_t lock(buffer_handle_t handle, int usage, const Rect& bounds); + + 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 @@ -51,16 +53,7 @@ public: private: friend class Singleton; BufferMapper(); - mutable Mutex mLock; gralloc_module_t const *mAllocMod; - - void logMapLocked(buffer_handle_t handle, const void* id); - void logUnmapLocked(buffer_handle_t handle, const void* id); - struct map_info_t { - const void* id; - CallStack stack; - }; - KeyedVector > mMapInfo; }; // --------------------------------------------------------------------------- diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h deleted file mode 100644 index a8b58539d192..000000000000 --- a/include/ui/EGLDisplaySurface.h +++ /dev/null @@ -1,86 +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_EGL_DISPLAY_SURFACE_H -#define ANDROID_EGL_DISPLAY_SURFACE_H - -#include -#include - -#include - -#include - -#include -#include - -#include - -struct copybit_device_t; -struct copybit_image_t; - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Region; -class Rect; - -class EGLDisplaySurface : public EGLNativeSurface -{ -public: - EGLDisplaySurface(); - ~EGLDisplaySurface(); - - int32_t getPageFlipCount() const; - void copyFrontToBack(const Region& copyback); - void copyFrontToImage(const copybit_image_t& dst); - void copyBackToImage(const copybit_image_t& dst); - - void setSwapRectangle(int l, int t, int w, int h); - -private: - static void hook_incRef(NativeWindowType window); - static void hook_decRef(NativeWindowType window); - static uint32_t hook_swapBuffers(NativeWindowType window); - - uint32_t swapBuffers(); - - status_t mapFrameBuffer(); - - enum { - PAGE_FLIP = 0x00000001 - }; - GGLSurface mFb[2]; - int mIndex; - uint32_t mFlags; - size_t mSize; - fb_var_screeninfo mInfo; - fb_fix_screeninfo mFinfo; - int32_t mPageFlipCount; - nsecs_t mTime; - int32_t mSwapCount; - nsecs_t mSleep; - uint32_t mFeatureFlags; - copybit_device_t* mBlitEngine; -}; - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_EGL_DISPLAY_SURFACE_H - diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/EGLNativeWindowSurface.h deleted file mode 100644 index 4b25655cf332..000000000000 --- a/include/ui/EGLNativeWindowSurface.h +++ /dev/null @@ -1,125 +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_EGL_NATIVE_WINDOW_SURFACE_H -#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H - -#include -#include - -#include -#include - -#include -#include - -#include - - -extern "C" EGLNativeWindowType android_createDisplaySurface(void); - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Surface; - - -class NativeBuffer - : public EGLNativeBase< - android_native_buffer_t, - NativeBuffer, - LightRefBase > -{ -public: - NativeBuffer(int w, int h, int f, int u) : BASE() { - android_native_buffer_t::width = w; - android_native_buffer_t::height = h; - android_native_buffer_t::format = f; - android_native_buffer_t::usage = u; - android_native_buffer_t::getHandle = getHandle; - } -public: - buffer_handle_t handle; -private: - friend class LightRefBase; - ~NativeBuffer() { }; // this class cannot be overloaded - static int getHandle(android_native_buffer_t const * base, buffer_handle_t* handle) { - *handle = getSelf(base)->handle; - return 0; - } -}; - -// --------------------------------------------------------------------------- - -class FramebufferNativeWindow - : public EGLNativeBase< - android_native_window_t, - FramebufferNativeWindow, - LightRefBase > -{ -public: - FramebufferNativeWindow(); - - framebuffer_device_t const * getDevice() const { return fbDev; } - -private: - friend class LightRefBase; - ~FramebufferNativeWindow(); // this class cannot be overloaded - static void connect(android_native_window_t* window); - static void disconnect(android_native_window_t* window); - static int setSwapInterval(android_native_window_t* window, int interval); - static int setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h); - static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); - static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); - static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); - - - static inline FramebufferNativeWindow* getSelf( - android_native_window_t* window) { - FramebufferNativeWindow* self = - static_cast(window); - return self; - } - - static inline FramebufferNativeWindow* getSelf( - android_native_base_t* window) { - return getSelf(reinterpret_cast(window)); - } - - - framebuffer_device_t* fbDev; - alloc_device_t* grDev; - - sp buffers[2]; - sp front; - - Rect mDirty; - - mutable Mutex mutex; - Condition mCondition; - int32_t mNumBuffers; - int32_t mNumFreeBuffers; - int32_t mBufferHead; -}; - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H - diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h new file mode 100644 index 000000000000..1d49cca401ae --- /dev/null +++ b/include/ui/FramebufferNativeWindow.h @@ -0,0 +1,111 @@ +/* + * 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_FRAMEBUFFER_NATIVE_WINDOW_H +#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H + +#include +#include + +#include +#include + +#include +#include + +#include + + +extern "C" EGLNativeWindowType android_createDisplaySurface(void); + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +class Surface; + + +class NativeBuffer + : public EGLNativeBase< + android_native_buffer_t, + NativeBuffer, + LightRefBase > +{ +public: + NativeBuffer(int w, int h, int f, int u) : BASE() { + android_native_buffer_t::width = w; + android_native_buffer_t::height = h; + android_native_buffer_t::format = f; + android_native_buffer_t::usage = u; + android_native_buffer_t::getHandle = getHandle; + } +public: + buffer_handle_t handle; +private: + friend class LightRefBase; + ~NativeBuffer() { }; // this class cannot be overloaded + static int getHandle(android_native_buffer_t const * base, buffer_handle_t* handle) { + *handle = getSelf(base)->handle; + return 0; + } +}; + +// --------------------------------------------------------------------------- + +class FramebufferNativeWindow + : public EGLNativeBase< + android_native_window_t, + FramebufferNativeWindow, + LightRefBase > +{ +public: + FramebufferNativeWindow(); + + framebuffer_device_t const * getDevice() const { return fbDev; } + + void setSwapRectangle(const Rect& dirty); + +private: + friend class LightRefBase; + ~FramebufferNativeWindow(); // this class cannot be overloaded + static void connect(android_native_window_t* window); + static void disconnect(android_native_window_t* window); + static int setSwapInterval(android_native_window_t* window, int interval); + static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); + static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); + static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); + + framebuffer_device_t* fbDev; + alloc_device_t* grDev; + + sp buffers[2]; + sp front; + + Rect mDirty; + + mutable Mutex mutex; + Condition mCondition; + int32_t mNumBuffers; + int32_t mNumFreeBuffers; + int32_t mBufferHead; +}; + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H + diff --git a/include/ui/Region.h b/include/ui/Region.h index 76896737f293..5efeff7d32ad 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -57,6 +57,7 @@ public: void clear(); void set(const Rect& r); + void set(uint32_t w, uint32_t h); Region& orSelf(const Rect& rhs); Region& andSelf(const Rect& rhs); diff --git a/include/ui/Surface.h b/include/ui/Surface.h index 16d2edb8e223..6eb06ae65f35 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -34,7 +34,9 @@ namespace android { // --------------------------------------------------------------------------- +class BufferMapper; class Rect; +class Surface; class SurfaceComposerClient; struct per_client_cblk_t; struct layer_cblk_t; @@ -52,6 +54,10 @@ public: return handle; } + status_t lock(uint32_t usage); + status_t lock(uint32_t usage, const Rect& rect); + status_t unlock(); + protected: SurfaceBuffer(); SurfaceBuffer(const Parcel& reply); @@ -59,7 +65,11 @@ protected: buffer_handle_t handle; 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; @@ -72,6 +82,8 @@ private: static int getHandle(android_native_buffer_t const * base, buffer_handle_t* handle); + + BufferMapper& mBufferMapper; }; // --------------------------------------------------------------------------- @@ -191,9 +203,8 @@ public: status_t lock(SurfaceInfo* info, Region* dirty, bool blocking = true); status_t unlockAndPost(); - // setSwapRectangle() is mainly used by EGL + // setSwapRectangle() is intended to be used by GL ES clients void setSwapRectangle(const Rect& r); - const Rect& swapRectangle() const; private: // can't be copied @@ -216,22 +227,14 @@ private: const sp& getISurface() const { return mSurface; } status_t getBufferLocked(int index); - - - - Region dirtyRegion() const; - void setDirtyRegion(const Region& region) const; - status_t validate(per_client_cblk_t const* cblk) const; static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty); + inline const BufferMapper& getBufferMapper() const { return mBufferMapper; } + inline BufferMapper& getBufferMapper() { return mBufferMapper; } - static void connect(android_native_window_t* window); - static void disconnect(android_native_window_t* window); static int setSwapInterval(android_native_window_t* window, int interval); - static int setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h); static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer); static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer); static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer); @@ -239,21 +242,27 @@ private: int dequeueBuffer(android_native_buffer_t** buffer); int lockBuffer(android_native_buffer_t* buffer); int queueBuffer(android_native_buffer_t* buffer); - + + status_t dequeueBuffer(sp* buffer); + status_t lockBuffer(const sp& buffer); + status_t queueBuffer(const sp& buffer); + alloc_device_t* mAllocDevice; sp mClient; sp mSurface; sp mBuffers[2]; - android_native_buffer_t* mLockedBuffer; + sp mLockedBuffer; SurfaceID mToken; uint32_t mIdentity; PixelFormat mFormat; uint32_t mFlags; mutable Region mDirtyRegion; - mutable Rect mSwapRectangle; + mutable Region mOldDirtyRegion; mutable uint8_t mBackbufferIndex; mutable Mutex mSurfaceLock; + Rect mSwapRectangle; + BufferMapper& mBufferMapper; }; }; // namespace android diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h index cbda0fd80db6..bd7f28cae3a1 100644 --- a/include/utils/RefBase.h +++ b/include/utils/RefBase.h @@ -156,6 +156,10 @@ public: delete static_cast(this); } } + //! DEBUGGING ONLY: Get current strong ref count. + inline int32_t getStrongCount() const { + return mCount; + } protected: inline ~LightRefBase() { } diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index 2b360d620595..639a82eaeb97 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -14,10 +14,7 @@ LOCAL_SRC_FILES:= \ LayerBlur.cpp \ LayerBitmap.cpp \ LayerDim.cpp \ - LayerOrientationAnim.cpp \ - LayerOrientationAnimRotate.cpp \ MessageQueue.cpp \ - OrientationAnimation.cpp \ SurfaceFlinger.cpp \ Tokenizer.cpp \ Transform.cpp diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp index ee36b6703a39..b45fe3489a9e 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index fec7c8770584..cee8b643dde6 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -16,20 +16,14 @@ */ #include -#include #include #include #include #include -#include - #include "BufferAllocator.h" -// FIXME: ANDROID_GRALLOC_DEBUG must only be used with *our* gralloc -#define ANDROID_GRALLOC_DEBUG 1 - namespace android { // --------------------------------------------------------------------------- @@ -67,8 +61,8 @@ void BufferAllocator::dump(String8& result) const const size_t c = list.size(); for (size_t i=0 ; idata[2]); -#endif - status_t err = mAllocDev->free(mAllocDev, handle); LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); -#if ANDROID_GRALLOC_DEBUG - if (base) { - LOGD("freeing mapped handle %p from:", handle); - CallStack s; - s.update(); - s.dump(""); - BufferMapper::get().dump(handle); - } -#endif - if (err == NO_ERROR) { Mutex::Autolock _l(sLock); KeyedVector& list(sAllocList); @@ -134,37 +114,5 @@ status_t BufferAllocator::free(buffer_handle_t handle) return err; } -status_t BufferAllocator::map(buffer_handle_t handle, void** addr) -{ - Mutex::Autolock _l(mLock); - status_t err = BufferMapper::get().map(handle, addr, this); - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - ssize_t idx = list.indexOfKey(handle); - if (idx >= 0) - list.editValueAt(idx).vaddr = addr; - } - - return err; -} - -status_t BufferAllocator::unmap(buffer_handle_t handle) -{ - Mutex::Autolock _l(mLock); - gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module; - status_t err = BufferMapper::get().unmap(handle, this); - if (err == NO_ERROR) { - Mutex::Autolock _l(sLock); - KeyedVector& list(sAllocList); - ssize_t idx = list.indexOfKey(handle); - if (idx >= 0) - list.editValueAt(idx).vaddr = 0; - } - - return err; -} - - // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h index 0b69b8ecd46f..a279deda941c 100644 --- a/libs/surfaceflinger/BufferAllocator.h +++ b/libs/surfaceflinger/BufferAllocator.h @@ -67,10 +67,6 @@ public: status_t free(buffer_handle_t handle); - status_t map(buffer_handle_t handle, void** addr); - - status_t unmap(buffer_handle_t handle); - void dump(String8& res) const; private: diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index 1f7211cc13ca..83ebd7a617d3 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -313,8 +313,7 @@ void DisplayHardware::flip(const Region& dirty) const } const Rect& b(newDirty.bounds()); - mNativeWindow->android_native_window_t::setSwapRectangle( - mNativeWindow.get(), b.left, b.top, b.width(), b.height()); + mNativeWindow->setSwapRectangle(b); mPageFlipCount++; eglSwapBuffers(dpy, surface); diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 8a7d46784f55..76259317482f 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -69,8 +69,6 @@ void Layer::destroy() { for (int i=0 ; i& buffer(frontBuffer().getBuffer()); - if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { + const sp& buffer(frontBuffer().getBuffer()); + if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { int index = mFrontBufferIndex; if (LIKELY(!mTextures[index].dirty)) { glBindTexture(GL_TEXTURE_2D, mTextures[index].name); @@ -197,12 +195,16 @@ void Layer::reloadTexture(const Region& dirty) } } else { GGLSurface t; - if (LIKELY(buffer->getBitmapSurface(&t) == NO_ERROR)) { + status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); + 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(); } loadTexture(dirty, mTextures[0].name, t, mTextures[0].width, mTextures[0].height); + buffer->unlock(); } } } @@ -225,8 +227,7 @@ void Layer::onDraw(const Region& clip) const GGLSurface t; sp buffer(frontBuffer().getBuffer()); - buffer->getBitmapSurface(&t); - drawWithOpenGL(clip, textureName, t); + drawWithOpenGL(clip, textureName, buffer); } sp Layer::peekBuffer() diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index ef5a9598d69e..cc9c586b421a 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -377,12 +377,14 @@ void LayerBase::clearWithOpenGL(const Region& clip) const } void LayerBase::drawWithOpenGL(const Region& clip, - GLint textureName, const GGLSurface& t, int transform) const + GLint textureName, const sp& buffer, int transform) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); - + const uint32_t width = buffer->width; + const uint32_t height = buffer->height; + // bind our texture validateTexture(textureName); glEnable(GL_TEXTURE_2D); @@ -457,14 +459,14 @@ void LayerBase::drawWithOpenGL(const Region& clip, if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { // find the smallest power-of-two that will accommodate our surface - GLuint tw = 1 << (31 - clz(t.width)); - GLuint th = 1 << (31 - clz(t.height)); - if (tw < t.width) tw <<= 1; - if (th < t.height) th <<= 1; + GLuint tw = 1 << (31 - clz(width)); + GLuint th = 1 << (31 - clz(height)); + if (tw < width) tw <<= 1; + if (th < height) th <<= 1; // this divide should be relatively fast because it's // a power-of-two (optimized path in libgcc) - GLfloat ws = GLfloat(t.width) /tw; - GLfloat hs = GLfloat(t.height)/th; + GLfloat ws = GLfloat(width) /tw; + GLfloat hs = GLfloat(height)/th; glScalef(ws, hs, 1.0f); } @@ -489,15 +491,15 @@ void LayerBase::drawWithOpenGL(const Region& clip, Region::iterator iterator(clip); if (iterator) { Rect r; - GLint crop[4] = { 0, t.height, t.width, -t.height }; + GLint crop[4] = { 0, height, width, -height }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); int x = tx(); int y = ty(); - y = fbHeight - (y + t.height); + y = fbHeight - (y + height); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); - glDrawTexiOES(x, y, 0, t.width, t.height); + glDrawTexiOES(x, y, 0, width, height); } } } diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index c177c2a4faf2..509dedd743f1 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -40,6 +40,7 @@ class DisplayHardware; class GraphicPlane; class Client; class SurfaceBuffer; +class Buffer; // --------------------------------------------------------------------------- @@ -239,7 +240,7 @@ protected: void drawWithOpenGL(const Region& clip, GLint textureName, - const GGLSurface& surface, + const sp& buffer, int transform = 0) const; void clearWithOpenGL(const Region& clip) const; diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index d633a2d52bf4..38d4bcf02f7d 100644 --- a/libs/surfaceflinger/LayerBitmap.cpp +++ b/libs/surfaceflinger/LayerBitmap.cpp @@ -52,10 +52,7 @@ Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) Buffer::~Buffer() { if (handle) { - BufferAllocator& allocator = BufferAllocator::get(); - if (usage & BufferAllocator::USAGE_SW_READ_MASK) { - allocator.unmap(handle); - } + BufferAllocator& allocator(BufferAllocator::get()); allocator.free(handle); } } @@ -107,9 +104,6 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) err = allocator.alloc(w, h, format, usage, &handle, &stride); if (err == NO_ERROR) { - if (usage & BufferAllocator::USAGE_SW_READ_MASK) { - err = allocator.map(handle, &bits); - } if (err == NO_ERROR) { width = w; height = h; @@ -120,31 +114,22 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) return err; } -status_t Buffer::getBitmapSurface(copybit_image_t* img) const +status_t Buffer::lock(GGLSurface* sur, uint32_t usage) { - img->w = stride ?: width; - img->h = mVStride ?: height; - img->format = format; - - // FIXME: this should use a native_handle - img->offset = 0; - img->base = bits; - img->fd = getHandle()->data[0]; - - return NO_ERROR; + status_t res = SurfaceBuffer::lock(usage); + 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(bits); + } + return res; } -status_t Buffer::getBitmapSurface(GGLSurface* sur) const -{ - sur->version = sizeof(GGLSurface); - sur->width = width; - sur->height = height; - sur->stride = stride; - sur->format = format; - sur->vstride = mVStride; - sur->data = static_cast(bits); - return NO_ERROR; -} + // =========================================================================== // LayerBitmap diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index e6737550f281..6e136a2ae764 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -73,9 +73,8 @@ public: PixelFormat getPixelFormat() const { return format; } Rect getBounds() const { return Rect(width, height); } - status_t getBitmapSurface(copybit_image_t* img) const; - status_t getBitmapSurface(GGLSurface* surface) const; - + status_t lock(GGLSurface* surface, uint32_t usage); + android_native_buffer_t* getNativeBuffer() const; private: diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 9339b8758cc1..8be91c9febf1 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -380,37 +380,37 @@ bool LayerBuffer::BufferSource::transformed() const void LayerBuffer::BufferSource::onDraw(const Region& clip) const { - sp buffer(getBuffer()); + // FIXME: we should get a native buffer here + /* + sp ourBbuffer(getBuffer()); if (UNLIKELY(buffer == 0)) { // nothing to do, we don't have a buffer mLayer.clearWithOpenGL(clip); return; } - status_t err = NO_ERROR; - NativeBuffer src(buffer->getBuffer()); - const Rect& transformedBounds = mLayer.getTransformedBounds(); - // FIXME: We should model this after the overlay stuff - if (UNLIKELY(mTextureName == -1LU)) { mTextureName = mLayer.createTexture(); } - GLuint w = 0; - GLuint h = 0; - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.crop.r; - t.height = src.crop.b; - t.stride = src.img.w; - t.vstride= src.img.h; - t.format = src.img.format; - t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset); - const Region dirty(Rect(t.width, t.height)); // FIXME: Use EGLImage extension for this - mLayer.loadTexture(dirty, mTextureName, t, w, h); - mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform); + + + + GGLSurface t; + status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY); + if (res == NO_ERROR) { + GLuint w = 0; + GLuint h = 0; + const Region dirty(Rect(buffer->width, buffer->height)); + mLayer.loadTexture(dirty, mTextureName, t, w, h); + buffer->unlock(); + } + if (res == NO_ERROR) { + mLayer.drawWithOpenGL(clip, mTextureName, buffer, mBufferHeap.transform); + } + */ } diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp deleted file mode 100644 index 41c42d177573..000000000000 --- a/libs/surfaceflinger/LayerOrientationAnim.cpp +++ /dev/null @@ -1,272 +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 "SurfaceFlinger" - -#include -#include -#include - -#include -#include -#include - -#include "BlurFilter.h" -#include "LayerBase.h" -#include "LayerOrientationAnim.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" -#include "OrientationAnimation.h" - -namespace android { -// --------------------------------------------------------------------------- - -const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80; -const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim"; - -// --------------------------------------------------------------------------- - -// Animation... -const float DURATION = ms2ns(200); -const float BOUNCES_PER_SECOND = 0.5f; -//const float BOUNCES_AMPLITUDE = 1.0f/16.0f; -const float BOUNCES_AMPLITUDE = 0; -const float DIM_TARGET = 0.40f; -//#define INTERPOLATED_TIME(_t) ((_t)*(_t)) -#define INTERPOLATED_TIME(_t) (_t) - -// --------------------------------------------------------------------------- - -LayerOrientationAnim::LayerOrientationAnim( - SurfaceFlinger* flinger, DisplayID display, - OrientationAnimation* anim, - const sp& bitmapIn, - const sp& bitmapOut) - : LayerOrientationAnimBase(flinger, display), mAnim(anim), - mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), - mTextureName(-1), mTextureNameIn(-1) -{ - // blur that texture. - mStartTime = systemTime(); - mFinishTime = 0; - mOrientationCompleted = false; - mFirstRedraw = false; - mLastNormalizedTime = 0; - mNeedsBlending = false; - mAlphaInLerp.set(1.0f, DIM_TARGET); - mAlphaOutLerp.set(0.5f, 1.0f); -} - -LayerOrientationAnim::~LayerOrientationAnim() -{ - if (mTextureName != -1U) { - glDeleteTextures(1, &mTextureName); - } - if (mTextureNameIn != -1U) { - glDeleteTextures(1, &mTextureNameIn); - } -} - -bool LayerOrientationAnim::needsBlending() const -{ - return mNeedsBlending; -} - -Point LayerOrientationAnim::getPhysicalSize() const -{ - const GraphicPlane& plane(graphicPlane(0)); - const DisplayHardware& hw(plane.displayHardware()); - return Point(hw.getWidth(), hw.getHeight()); -} - -void LayerOrientationAnim::validateVisibility(const Transform&) -{ - const Layer::State& s(drawingState()); - const Transform tr(s.transform); - const Point size(getPhysicalSize()); - uint32_t w = size.x; - uint32_t h = size.y; - mTransformedBounds = tr.makeBounds(w, h); - mLeft = tr.tx(); - mTop = tr.ty(); - transparentRegionScreen.clear(); - mTransformed = true; -} - -void LayerOrientationAnim::onOrientationCompleted() -{ - mFinishTime = systemTime(); - mOrientationCompleted = true; - mFirstRedraw = true; - mNeedsBlending = true; - mFlinger->invalidateLayerVisibility(this); -} - -void LayerOrientationAnim::onDraw(const Region& clip) const -{ - const nsecs_t now = systemTime(); - float alphaIn, alphaOut; - - if (mOrientationCompleted) { - if (mFirstRedraw) { - mFirstRedraw = false; - - // make a copy of what's on screen - copybit_image_t image; - mBitmapOut->getBitmapSurface(&image); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - hw.copyBackToImage(image); - - // and erase the screen for this round - glDisable(GL_BLEND); - glDisable(GL_DITHER); - glDisable(GL_SCISSOR_TEST); - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT); - - // FIXME: code below is gross - mNeedsBlending = false; - LayerOrientationAnim* self(const_cast(this)); - mFlinger->invalidateLayerVisibility(self); - } - - // make sure pick-up where we left off - const float duration = DURATION * mLastNormalizedTime; - const float normalizedTime = (float(now - mFinishTime) / duration); - if (normalizedTime <= 1.0f) { - const float interpolatedTime = INTERPOLATED_TIME(normalizedTime); - alphaIn = mAlphaInLerp.getOut(); - alphaOut = mAlphaOutLerp(interpolatedTime); - } else { - mAnim->onAnimationFinished(); - alphaIn = mAlphaInLerp.getOut(); - alphaOut = mAlphaOutLerp.getOut(); - } - } else { - const float normalizedTime = float(now - mStartTime) / DURATION; - if (normalizedTime <= 1.0f) { - mLastNormalizedTime = normalizedTime; - const float interpolatedTime = INTERPOLATED_TIME(normalizedTime); - alphaIn = mAlphaInLerp(interpolatedTime); - alphaOut = 0.0f; - } else { - mLastNormalizedTime = 1.0f; - const float to_seconds = DURATION / seconds(1); - alphaIn = mAlphaInLerp.getOut(); - if (BOUNCES_AMPLITUDE > 0.0f) { - const float phi = BOUNCES_PER_SECOND * - (((normalizedTime - 1.0f) * to_seconds)*M_PI*2); - if (alphaIn > 1.0f) alphaIn = 1.0f; - else if (alphaIn < 0.0f) alphaIn = 0.0f; - alphaIn += BOUNCES_AMPLITUDE * (1.0f - cosf(phi)); - } - alphaOut = 0.0f; - } - mAlphaOutLerp.setIn(alphaIn); - } - drawScaled(1.0f, alphaIn, alphaOut); -} - -void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut) const -{ - copybit_image_t dst; - const GraphicPlane& plane(graphicPlane(0)); - const DisplayHardware& hw(plane.displayHardware()); - //hw.getDisplaySurface(&dst); - - // clear screen - // TODO: with update on demand, we may be able - // to not erase the screen at all during the animation - if (!mOrientationCompleted) { - if (scale==1.0f && (alphaIn>=1.0f || alphaOut>=1.0f)) { - // we don't need to erase the screen in that case - } else { - glDisable(GL_BLEND); - glDisable(GL_DITHER); - glDisable(GL_SCISSOR_TEST); - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT); - } - } - - copybit_image_t src; - mBitmapIn->getBitmapSurface(&src); - - copybit_image_t srcOut; - mBitmapOut->getBitmapSurface(&srcOut); - - const int w = dst.w*scale; - const int h = dst.h*scale; - const int xc = uint32_t(dst.w-w)/2; - const int yc = uint32_t(dst.h-h)/2; - const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; - const copybit_rect_t srect = { 0, 0, src.w, src.h }; - const Region reg(Rect( drect.l, drect.t, drect.r, drect.b )); - - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.w; - t.height = src.h; - t.stride = src.w; - t.vstride= src.h; - t.format = src.format; - t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - - Transform tr; - tr.set(scale,0,0,scale); - tr.set(xc, yc); - - // FIXME: we should not access mVertices and mDrawingState like that, - // but since we control the animation, we know it's going to work okay. - // eventually we'd need a more formal way of doing things like this. - LayerOrientationAnim& self(const_cast(*this)); - tr.transform(self.mVertices[0], 0, 0); - tr.transform(self.mVertices[1], 0, src.h); - tr.transform(self.mVertices[2], src.w, src.h); - tr.transform(self.mVertices[3], src.w, 0); - if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { - // Too slow to do this in software - self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter; - } - - if (alphaIn > 0.0f) { - t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - if (UNLIKELY(mTextureNameIn == -1LU)) { - mTextureNameIn = createTexture(); - GLuint w=0, h=0; - const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureNameIn, t, w, h); - } - self.mDrawingState.alpha = int(alphaIn*255); - drawWithOpenGL(reg, mTextureNameIn, t); - } - - if (alphaOut > 0.0f) { - t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset); - if (UNLIKELY(mTextureName == -1LU)) { - mTextureName = createTexture(); - GLuint w=0, h=0; - const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureName, t, w, h); - } - self.mDrawingState.alpha = int(alphaOut*255); - drawWithOpenGL(reg, mTextureName, t); - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/LayerOrientationAnim.h deleted file mode 100644 index 472c45a1afef..000000000000 --- a/libs/surfaceflinger/LayerOrientationAnim.h +++ /dev/null @@ -1,112 +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_ORIENTATION_ANIM_H -#define ANDROID_LAYER_ORIENTATION_ANIM_H - -#include -#include -#include -#include - -#include "LayerBase.h" -#include "LayerBitmap.h" - -namespace android { - -// --------------------------------------------------------------------------- -class OrientationAnimation; - - -class LayerOrientationAnimBase : public LayerBase -{ -public: - LayerOrientationAnimBase(SurfaceFlinger* flinger, DisplayID display) - : LayerBase(flinger, display) { - } - virtual void onOrientationCompleted() = 0; -}; - -// --------------------------------------------------------------------------- - -class LayerOrientationAnim : public LayerOrientationAnimBase -{ -public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - - LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display, - OrientationAnimation* anim, - const sp& bitmapIn, - const sp& bitmapOut); - virtual ~LayerOrientationAnim(); - - void onOrientationCompleted(); - - virtual void onDraw(const Region& clip) const; - virtual Point getPhysicalSize() const; - virtual void validateVisibility(const Transform& globalTransform); - virtual bool needsBlending() const; - virtual bool isSecure() const { return false; } -private: - void drawScaled(float scale, float alphaIn, float alphaOut) const; - - class Lerp { - float in; - float outMinusIn; - public: - Lerp() : in(0), outMinusIn(0) { } - Lerp(float in, float out) : in(in), outMinusIn(out-in) { } - float getIn() const { return in; }; - float getOut() const { return in + outMinusIn; } - void set(float in, float out) { - this->in = in; - this->outMinusIn = out-in; - } - void setIn(float in) { - this->in = in; - } - void setOut(float out) { - this->outMinusIn = out - this->in; - } - float operator()(float t) const { - return outMinusIn*t + in; - } - }; - - OrientationAnimation* mAnim; - sp mBitmapIn; - sp mBitmapOut; - nsecs_t mStartTime; - nsecs_t mFinishTime; - bool mOrientationCompleted; - mutable bool mFirstRedraw; - mutable float mLastNormalizedTime; - mutable GLuint mTextureName; - mutable GLuint mTextureNameIn; - mutable bool mNeedsBlending; - - mutable Lerp mAlphaInLerp; - mutable Lerp mAlphaOutLerp; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_ORIENTATION_ANIM_H diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp deleted file mode 100644 index dc6b632a694d..000000000000 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp +++ /dev/null @@ -1,269 +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 "SurfaceFlinger" - -#include -#include -#include - -#include -#include - -#include "LayerBase.h" -#include "LayerOrientationAnim.h" -#include "LayerOrientationAnimRotate.h" -#include "SurfaceFlinger.h" -#include "DisplayHardware/DisplayHardware.h" -#include "OrientationAnimation.h" - -namespace android { -// --------------------------------------------------------------------------- - -const uint32_t LayerOrientationAnimRotate::typeInfo = LayerBase::typeInfo | 0x100; -const char* const LayerOrientationAnimRotate::typeID = "LayerOrientationAnimRotate"; - -// --------------------------------------------------------------------------- - -const float ROTATION = M_PI * 0.5f; -const float ROTATION_FACTOR = 1.0f; // 1.0 or 2.0 -const float DURATION = ms2ns(200); -const float BOUNCES_PER_SECOND = 0.8; -const float BOUNCES_AMPLITUDE = (5.0f/180.f) * M_PI; - -LayerOrientationAnimRotate::LayerOrientationAnimRotate( - SurfaceFlinger* flinger, DisplayID display, - OrientationAnimation* anim, - const sp& bitmapIn, - const sp& bitmapOut) - : LayerOrientationAnimBase(flinger, display), mAnim(anim), - mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), - mTextureName(-1), mTextureNameIn(-1) -{ - mStartTime = systemTime(); - mFinishTime = 0; - mOrientationCompleted = false; - mFirstRedraw = false; - mLastNormalizedTime = 0; - mLastAngle = 0; - mLastScale = 0; - mNeedsBlending = false; - const GraphicPlane& plane(graphicPlane(0)); - mOriginalTargetOrientation = plane.getOrientation(); -} - -LayerOrientationAnimRotate::~LayerOrientationAnimRotate() -{ - if (mTextureName != -1U) { - glDeleteTextures(1, &mTextureName); - } - if (mTextureNameIn != -1U) { - glDeleteTextures(1, &mTextureNameIn); - } -} - -bool LayerOrientationAnimRotate::needsBlending() const -{ - return mNeedsBlending; -} - -Point LayerOrientationAnimRotate::getPhysicalSize() const -{ - const GraphicPlane& plane(graphicPlane(0)); - const DisplayHardware& hw(plane.displayHardware()); - return Point(hw.getWidth(), hw.getHeight()); -} - -void LayerOrientationAnimRotate::validateVisibility(const Transform&) -{ - const Layer::State& s(drawingState()); - const Transform tr(s.transform); - const Point size(getPhysicalSize()); - uint32_t w = size.x; - uint32_t h = size.y; - mTransformedBounds = tr.makeBounds(w, h); - mLeft = tr.tx(); - mTop = tr.ty(); - transparentRegionScreen.clear(); - mTransformed = true; -} - -void LayerOrientationAnimRotate::onOrientationCompleted() -{ - mFinishTime = systemTime(); - mOrientationCompleted = true; - mFirstRedraw = true; - mNeedsBlending = true; - mFlinger->invalidateLayerVisibility(this); -} - -void LayerOrientationAnimRotate::onDraw(const Region& clip) const -{ - // Animation... - - const nsecs_t now = systemTime(); - float angle, scale, alpha; - - if (mOrientationCompleted) { - if (mFirstRedraw) { - // make a copy of what's on screen - copybit_image_t image; - mBitmapIn->getBitmapSurface(&image); - const DisplayHardware& hw(graphicPlane(0).displayHardware()); - hw.copyBackToImage(image); - - // FIXME: code below is gross - mFirstRedraw = false; - mNeedsBlending = false; - LayerOrientationAnimRotate* self(const_cast(this)); - mFlinger->invalidateLayerVisibility(self); - } - - // make sure pick-up where we left off - const float duration = DURATION * mLastNormalizedTime; - const float normalizedTime = (float(now - mFinishTime) / duration); - if (normalizedTime <= 1.0f) { - const float squaredTime = normalizedTime*normalizedTime; - angle = (ROTATION*ROTATION_FACTOR - mLastAngle)*squaredTime + mLastAngle; - scale = (1.0f - mLastScale)*squaredTime + mLastScale; - alpha = normalizedTime; - } else { - mAnim->onAnimationFinished(); - angle = ROTATION; - alpha = 1.0f; - scale = 1.0f; - } - } else { - // FIXME: works only for portrait framebuffers - const Point size(getPhysicalSize()); - const float TARGET_SCALE = size.x * (1.0f / size.y); - const float normalizedTime = float(now - mStartTime) / DURATION; - if (normalizedTime <= 1.0f) { - mLastNormalizedTime = normalizedTime; - const float squaredTime = normalizedTime*normalizedTime; - angle = ROTATION * squaredTime; - scale = (TARGET_SCALE - 1.0f)*squaredTime + 1.0f; - alpha = 0; - } else { - mLastNormalizedTime = 1.0f; - angle = ROTATION; - if (BOUNCES_AMPLITUDE) { - const float to_seconds = DURATION / seconds(1); - const float phi = BOUNCES_PER_SECOND * - (((normalizedTime - 1.0f) * to_seconds)*M_PI*2); - angle += BOUNCES_AMPLITUDE * sinf(phi); - } - scale = TARGET_SCALE; - alpha = 0; - } - mLastAngle = angle; - mLastScale = scale; - } - drawScaled(angle, scale, alpha); -} - -void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const -{ - copybit_image_t dst; - const GraphicPlane& plane(graphicPlane(0)); - const DisplayHardware& hw(plane.displayHardware()); - //hw.getDisplaySurface(&dst); - - // clear screen - // TODO: with update on demand, we may be able - // to not erase the screen at all during the animation - glDisable(GL_BLEND); - glDisable(GL_DITHER); - glDisable(GL_SCISSOR_TEST); - glClearColor(0,0,0,0); - glClear(GL_COLOR_BUFFER_BIT); - - const int w = dst.w; - const int h = dst.h; - - copybit_image_t src; - mBitmapIn->getBitmapSurface(&src); - const copybit_rect_t srect = { 0, 0, src.w, src.h }; - - - GGLSurface t; - t.version = sizeof(GGLSurface); - t.width = src.w; - t.height = src.h; - t.stride = src.w; - t.vstride= src.h; - t.format = src.format; - t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - - if (!mOriginalTargetOrientation) { - f = -f; - } - - Transform tr; - tr.set(f, w*0.5f, h*0.5f); - tr.scale(s, w*0.5f, h*0.5f); - - // FIXME: we should not access mVertices and mDrawingState like that, - // but since we control the animation, we know it's going to work okay. - // eventually we'd need a more formal way of doing things like this. - LayerOrientationAnimRotate& self(const_cast(*this)); - tr.transform(self.mVertices[0], 0, 0); - tr.transform(self.mVertices[1], 0, src.h); - tr.transform(self.mVertices[2], src.w, src.h); - tr.transform(self.mVertices[3], src.w, 0); - - if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { - // Too slow to do this in software - self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter; - } - - if (UNLIKELY(mTextureName == -1LU)) { - mTextureName = createTexture(); - GLuint w=0, h=0; - const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureName, t, w, h); - } - self.mDrawingState.alpha = 255; //-int(alpha*255); - const Region clip(Rect( srect.l, srect.t, srect.r, srect.b )); - drawWithOpenGL(clip, mTextureName, t); - - if (alpha > 0) { - const float sign = (!mOriginalTargetOrientation) ? 1.0f : -1.0f; - tr.set(f + sign*(M_PI * 0.5f * ROTATION_FACTOR), w*0.5f, h*0.5f); - tr.scale(s, w*0.5f, h*0.5f); - tr.transform(self.mVertices[0], 0, 0); - tr.transform(self.mVertices[1], 0, src.h); - tr.transform(self.mVertices[2], src.w, src.h); - tr.transform(self.mVertices[3], src.w, 0); - - copybit_image_t src; - mBitmapIn->getBitmapSurface(&src); - t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); - if (UNLIKELY(mTextureNameIn == -1LU)) { - mTextureNameIn = createTexture(); - GLuint w=0, h=0; - const Region dirty(Rect(t.width, t.height)); - loadTexture(dirty, mTextureNameIn, t, w, h); - } - self.mDrawingState.alpha = int(alpha*255); - const Region clip(Rect( srect.l, srect.t, srect.r, srect.b )); - drawWithOpenGL(clip, mTextureNameIn, t); - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/LayerOrientationAnimRotate.h deleted file mode 100644 index a675c79b5176..000000000000 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.h +++ /dev/null @@ -1,77 +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_ORIENTATION_ANIM_ROTATE_H -#define ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H - -#include -#include -#include -#include - -#include "LayerBase.h" -#include "LayerBitmap.h" - -namespace android { - -// --------------------------------------------------------------------------- -class OrientationAnimation; - -class LayerOrientationAnimRotate : public LayerOrientationAnimBase -{ -public: - static const uint32_t typeInfo; - static const char* const typeID; - virtual char const* getTypeID() const { return typeID; } - virtual uint32_t getTypeInfo() const { return typeInfo; } - - LayerOrientationAnimRotate(SurfaceFlinger* flinger, DisplayID display, - OrientationAnimation* anim, - const sp& bitmapIn, - const sp& bitmapOut); - virtual ~LayerOrientationAnimRotate(); - - void onOrientationCompleted(); - - virtual void onDraw(const Region& clip) const; - virtual Point getPhysicalSize() const; - virtual void validateVisibility(const Transform& globalTransform); - virtual bool needsBlending() const; - virtual bool isSecure() const { return false; } -private: - void drawScaled(float angle, float scale, float alpha) const; - - OrientationAnimation* mAnim; - sp mBitmapIn; - sp mBitmapOut; - nsecs_t mStartTime; - nsecs_t mFinishTime; - bool mOrientationCompleted; - int mOriginalTargetOrientation; - mutable bool mFirstRedraw; - mutable float mLastNormalizedTime; - mutable float mLastAngle; - mutable float mLastScale; - mutable GLuint mTextureName; - mutable GLuint mTextureNameIn; - mutable bool mNeedsBlending; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/OrientationAnimation.cpp deleted file mode 100644 index a6c9c28d0ba8..000000000000 --- a/libs/surfaceflinger/OrientationAnimation.cpp +++ /dev/null @@ -1,150 +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 "LayerOrientationAnim.h" -#include "LayerOrientationAnimRotate.h" -#include "OrientationAnimation.h" -#include "SurfaceFlinger.h" - -#include "DisplayHardware/DisplayHardware.h" - -namespace android { - -// --------------------------------------------------------------------------- - -OrientationAnimation::OrientationAnimation(const sp& flinger) - : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE) -{ -} - -OrientationAnimation::~OrientationAnimation() -{ -} - -void OrientationAnimation::onOrientationChanged(uint32_t type) -{ - if (mState == DONE) { - mType = type; - if (!(type & ISurfaceComposer::eOrientationAnimationDisable)) { - mState = PREPARE; - } - } -} - -void OrientationAnimation::onAnimationFinished() -{ - if (mState != DONE) - mState = FINISH; -} - -bool OrientationAnimation::run_impl() -{ - bool skip_frame; - switch (mState) { - default: - case DONE: - skip_frame = done(); - break; - case PREPARE: - skip_frame = prepare(); - break; - case PHASE1: - skip_frame = phase1(); - break; - case PHASE2: - skip_frame = phase2(); - break; - case FINISH: - skip_frame = finished(); - break; - } - return skip_frame; -} - -bool OrientationAnimation::done() -{ - return done_impl(); -} - -bool OrientationAnimation::prepare() -{ - mState = PHASE1; - - const GraphicPlane& plane(mFlinger->graphicPlane(0)); - const DisplayHardware& hw(plane.displayHardware()); - const uint32_t w = hw.getWidth(); - const uint32_t h = hw.getHeight(); - - sp bitmap = new Buffer(w, h, hw.getFormat()); - sp bitmapIn = new Buffer(w, h, hw.getFormat()); - - copybit_image_t front; - bitmap->getBitmapSurface(&front); - hw.copyFrontToImage(front); // FIXME: we need an extension to do this - - sp l; - - if (mType & 0x80) { - l = new LayerOrientationAnimRotate( - mFlinger.get(), 0, this, bitmap, bitmapIn); - } else { - l = new LayerOrientationAnim( - mFlinger.get(), 0, this, bitmap, bitmapIn); - } - - l->initStates(w, h, 0); - l->setLayer(INT_MAX-1); - mFlinger->addLayer(l); - mLayerOrientationAnim = l; - return true; -} - -bool OrientationAnimation::phase1() -{ - if (mFlinger->isFrozen() == false) { - // start phase 2 - mState = PHASE2; - mLayerOrientationAnim->onOrientationCompleted(); - mLayerOrientationAnim->invalidate(); - return true; - - } - mLayerOrientationAnim->invalidate(); - return false; -} - -bool OrientationAnimation::phase2() -{ - // do the 2nd phase of the animation - mLayerOrientationAnim->invalidate(); - return false; -} - -bool OrientationAnimation::finished() -{ - mState = DONE; - mFlinger->removeLayer(mLayerOrientationAnim); - mLayerOrientationAnim.clear(); - return true; -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/OrientationAnimation.h deleted file mode 100644 index 8ba66210e873..000000000000 --- a/libs/surfaceflinger/OrientationAnimation.h +++ /dev/null @@ -1,84 +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_ORIENTATION_ANIMATION_H -#define ANDROID_ORIENTATION_ANIMATION_H - -#include -#include - -#include "SurfaceFlinger.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class SurfaceFlinger; -class MemoryDealer; -class LayerOrientationAnim; - -class OrientationAnimation -{ -public: - OrientationAnimation(const sp& flinger); - virtual ~OrientationAnimation(); - - void onOrientationChanged(uint32_t type); - void onAnimationFinished(); - inline bool run() { - if (LIKELY(mState == DONE)) - return done_impl(); - return run_impl(); - } - -private: - enum { - DONE = 0, - PREPARE, - PHASE1, - PHASE2, - FINISH - }; - - bool run_impl(); - inline bool done_impl() { - if (mFlinger->isFrozen()) { - // we are not allowed to draw, but pause a bit to make sure - // apps don't end up using the whole CPU, if they depend on - // surfaceflinger for synchronization. - usleep(8333); // 8.3ms ~ 120fps - return true; - } - return false; - } - - bool done(); - bool prepare(); - bool phase1(); - bool phase2(); - bool finished(); - - sp mFlinger; - sp< LayerOrientationAnimBase > mLayerOrientationAnim; - int mState; - uint32_t mType; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_ORIENTATION_ANIMATION_H diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 6b421588e19c..5fd979e0614b 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -50,8 +50,6 @@ #include "LayerBuffer.h" #include "LayerDim.h" #include "LayerBitmap.h" -#include "LayerOrientationAnim.h" -#include "OrientationAnimation.h" #include "SurfaceFlinger.h" #include "DisplayHardware/DisplayHardware.h" @@ -206,7 +204,6 @@ void SurfaceFlinger::init() SurfaceFlinger::~SurfaceFlinger() { glDeleteTextures(1, &mWormholeTexName); - delete mOrientationAnimation; } overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const @@ -399,8 +396,6 @@ status_t SurfaceFlinger::readyToRun() * We're now ready to accept clients... */ - mOrientationAnimation = new OrientationAnimation(this); - // the boot animation! if (mDebugNoBootAnimation == false) mBootAnimation = new BootAnimation(this); @@ -513,16 +508,17 @@ bool SurfaceFlinger::threadLoop() void SurfaceFlinger::postFramebuffer() { - const bool skip = mOrientationAnimation->run(); - if (UNLIKELY(skip)) { + if (isFrozen()) { + // we are not allowed to draw, but pause a bit to make sure + // apps don't end up using the whole CPU, if they depend on + // surfaceflinger for synchronization. + usleep(8333); // 8.3ms ~ 120fps return; } if (!mInvalidRegion.isEmpty()) { const DisplayHardware& hw(graphicPlane(0).displayHardware()); - hw.flip(mInvalidRegion); - mInvalidRegion.clear(); } } @@ -616,7 +612,6 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) mVisibleRegionsDirty = true; mDirtyRegion.set(hw.bounds()); mFreezeDisplayTime = 0; - mOrientationAnimation->onOrientationChanged(type); } if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { @@ -893,19 +888,26 @@ void SurfaceFlinger::executeScheduledBroadcasts() void SurfaceFlinger::debugFlashRegions() { - if (UNLIKELY(!mDirtyRegion.isRect())) { - // TODO: do this only if we don't have preserving - // swapBuffer. If we don't have update-on-demand, - // redraw everything. - composeSurfaces(Region(mDirtyRegion.bounds())); - } - + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + const uint32_t flags = hw.getFlags(); + if (!(flags & DisplayHardware::BUFFER_PRESERVED)) { + const Region repaint((flags & DisplayHardware::UPDATE_ON_DEMAND) ? + mDirtyRegion.bounds() : hw.bounds()); + composeSurfaces(repaint); + } + glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); - glColor4x(0x10000, 0, 0x10000, 0x10000); + static int toggle = 0; + toggle = 1 - toggle; + if (toggle) { + glColor4x(0x10000, 0, 0x10000, 0x10000); + } else { + glColor4x(0x10000, 0x10000, 0, 0x10000); + } Rect r; Region::iterator iterator(mDirtyRegion); @@ -919,8 +921,7 @@ void SurfaceFlinger::debugFlashRegions() glVertexPointer(2, GL_FLOAT, 0, vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - - const DisplayHardware& hw(graphicPlane(0).displayHardware()); + hw.flip(mDirtyRegion.merge(mInvalidRegion)); mInvalidRegion.clear(); diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 319f80e9e926..d5e525273c77 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -55,8 +55,6 @@ class DisplayHardware; class FreezeLock; class Layer; class LayerBuffer; -class LayerOrientationAnim; -class OrientationAnimation; typedef int32_t ClientID; @@ -335,8 +333,6 @@ private: bool mFreezeDisplay; int32_t mFreezeCount; nsecs_t mFreezeDisplayTime; - friend class OrientationAnimation; - OrientationAnimation* mOrientationAnimation; // don't use a lock for these, we don't care int mDebugRegion; diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp new file mode 100644 index 000000000000..41c42d177573 --- /dev/null +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp @@ -0,0 +1,272 @@ +/* + * 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 "SurfaceFlinger" + +#include +#include +#include + +#include +#include +#include + +#include "BlurFilter.h" +#include "LayerBase.h" +#include "LayerOrientationAnim.h" +#include "SurfaceFlinger.h" +#include "DisplayHardware/DisplayHardware.h" +#include "OrientationAnimation.h" + +namespace android { +// --------------------------------------------------------------------------- + +const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80; +const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim"; + +// --------------------------------------------------------------------------- + +// Animation... +const float DURATION = ms2ns(200); +const float BOUNCES_PER_SECOND = 0.5f; +//const float BOUNCES_AMPLITUDE = 1.0f/16.0f; +const float BOUNCES_AMPLITUDE = 0; +const float DIM_TARGET = 0.40f; +//#define INTERPOLATED_TIME(_t) ((_t)*(_t)) +#define INTERPOLATED_TIME(_t) (_t) + +// --------------------------------------------------------------------------- + +LayerOrientationAnim::LayerOrientationAnim( + SurfaceFlinger* flinger, DisplayID display, + OrientationAnimation* anim, + const sp& bitmapIn, + const sp& bitmapOut) + : LayerOrientationAnimBase(flinger, display), mAnim(anim), + mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), + mTextureName(-1), mTextureNameIn(-1) +{ + // blur that texture. + mStartTime = systemTime(); + mFinishTime = 0; + mOrientationCompleted = false; + mFirstRedraw = false; + mLastNormalizedTime = 0; + mNeedsBlending = false; + mAlphaInLerp.set(1.0f, DIM_TARGET); + mAlphaOutLerp.set(0.5f, 1.0f); +} + +LayerOrientationAnim::~LayerOrientationAnim() +{ + if (mTextureName != -1U) { + glDeleteTextures(1, &mTextureName); + } + if (mTextureNameIn != -1U) { + glDeleteTextures(1, &mTextureNameIn); + } +} + +bool LayerOrientationAnim::needsBlending() const +{ + return mNeedsBlending; +} + +Point LayerOrientationAnim::getPhysicalSize() const +{ + const GraphicPlane& plane(graphicPlane(0)); + const DisplayHardware& hw(plane.displayHardware()); + return Point(hw.getWidth(), hw.getHeight()); +} + +void LayerOrientationAnim::validateVisibility(const Transform&) +{ + const Layer::State& s(drawingState()); + const Transform tr(s.transform); + const Point size(getPhysicalSize()); + uint32_t w = size.x; + uint32_t h = size.y; + mTransformedBounds = tr.makeBounds(w, h); + mLeft = tr.tx(); + mTop = tr.ty(); + transparentRegionScreen.clear(); + mTransformed = true; +} + +void LayerOrientationAnim::onOrientationCompleted() +{ + mFinishTime = systemTime(); + mOrientationCompleted = true; + mFirstRedraw = true; + mNeedsBlending = true; + mFlinger->invalidateLayerVisibility(this); +} + +void LayerOrientationAnim::onDraw(const Region& clip) const +{ + const nsecs_t now = systemTime(); + float alphaIn, alphaOut; + + if (mOrientationCompleted) { + if (mFirstRedraw) { + mFirstRedraw = false; + + // make a copy of what's on screen + copybit_image_t image; + mBitmapOut->getBitmapSurface(&image); + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + hw.copyBackToImage(image); + + // and erase the screen for this round + glDisable(GL_BLEND); + glDisable(GL_DITHER); + glDisable(GL_SCISSOR_TEST); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + + // FIXME: code below is gross + mNeedsBlending = false; + LayerOrientationAnim* self(const_cast(this)); + mFlinger->invalidateLayerVisibility(self); + } + + // make sure pick-up where we left off + const float duration = DURATION * mLastNormalizedTime; + const float normalizedTime = (float(now - mFinishTime) / duration); + if (normalizedTime <= 1.0f) { + const float interpolatedTime = INTERPOLATED_TIME(normalizedTime); + alphaIn = mAlphaInLerp.getOut(); + alphaOut = mAlphaOutLerp(interpolatedTime); + } else { + mAnim->onAnimationFinished(); + alphaIn = mAlphaInLerp.getOut(); + alphaOut = mAlphaOutLerp.getOut(); + } + } else { + const float normalizedTime = float(now - mStartTime) / DURATION; + if (normalizedTime <= 1.0f) { + mLastNormalizedTime = normalizedTime; + const float interpolatedTime = INTERPOLATED_TIME(normalizedTime); + alphaIn = mAlphaInLerp(interpolatedTime); + alphaOut = 0.0f; + } else { + mLastNormalizedTime = 1.0f; + const float to_seconds = DURATION / seconds(1); + alphaIn = mAlphaInLerp.getOut(); + if (BOUNCES_AMPLITUDE > 0.0f) { + const float phi = BOUNCES_PER_SECOND * + (((normalizedTime - 1.0f) * to_seconds)*M_PI*2); + if (alphaIn > 1.0f) alphaIn = 1.0f; + else if (alphaIn < 0.0f) alphaIn = 0.0f; + alphaIn += BOUNCES_AMPLITUDE * (1.0f - cosf(phi)); + } + alphaOut = 0.0f; + } + mAlphaOutLerp.setIn(alphaIn); + } + drawScaled(1.0f, alphaIn, alphaOut); +} + +void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut) const +{ + copybit_image_t dst; + const GraphicPlane& plane(graphicPlane(0)); + const DisplayHardware& hw(plane.displayHardware()); + //hw.getDisplaySurface(&dst); + + // clear screen + // TODO: with update on demand, we may be able + // to not erase the screen at all during the animation + if (!mOrientationCompleted) { + if (scale==1.0f && (alphaIn>=1.0f || alphaOut>=1.0f)) { + // we don't need to erase the screen in that case + } else { + glDisable(GL_BLEND); + glDisable(GL_DITHER); + glDisable(GL_SCISSOR_TEST); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + } + } + + copybit_image_t src; + mBitmapIn->getBitmapSurface(&src); + + copybit_image_t srcOut; + mBitmapOut->getBitmapSurface(&srcOut); + + const int w = dst.w*scale; + const int h = dst.h*scale; + const int xc = uint32_t(dst.w-w)/2; + const int yc = uint32_t(dst.h-h)/2; + const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; + const copybit_rect_t srect = { 0, 0, src.w, src.h }; + const Region reg(Rect( drect.l, drect.t, drect.r, drect.b )); + + GGLSurface t; + t.version = sizeof(GGLSurface); + t.width = src.w; + t.height = src.h; + t.stride = src.w; + t.vstride= src.h; + t.format = src.format; + t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); + + Transform tr; + tr.set(scale,0,0,scale); + tr.set(xc, yc); + + // FIXME: we should not access mVertices and mDrawingState like that, + // but since we control the animation, we know it's going to work okay. + // eventually we'd need a more formal way of doing things like this. + LayerOrientationAnim& self(const_cast(*this)); + tr.transform(self.mVertices[0], 0, 0); + tr.transform(self.mVertices[1], 0, src.h); + tr.transform(self.mVertices[2], src.w, src.h); + tr.transform(self.mVertices[3], src.w, 0); + if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { + // Too slow to do this in software + self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter; + } + + if (alphaIn > 0.0f) { + t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); + if (UNLIKELY(mTextureNameIn == -1LU)) { + mTextureNameIn = createTexture(); + GLuint w=0, h=0; + const Region dirty(Rect(t.width, t.height)); + loadTexture(dirty, mTextureNameIn, t, w, h); + } + self.mDrawingState.alpha = int(alphaIn*255); + drawWithOpenGL(reg, mTextureNameIn, t); + } + + if (alphaOut > 0.0f) { + t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset); + if (UNLIKELY(mTextureName == -1LU)) { + mTextureName = createTexture(); + GLuint w=0, h=0; + const Region dirty(Rect(t.width, t.height)); + loadTexture(dirty, mTextureName, t, w, h); + } + self.mDrawingState.alpha = int(alphaOut*255); + drawWithOpenGL(reg, mTextureName, t); + } +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h new file mode 100644 index 000000000000..472c45a1afef --- /dev/null +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h @@ -0,0 +1,112 @@ +/* + * 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_ORIENTATION_ANIM_H +#define ANDROID_LAYER_ORIENTATION_ANIM_H + +#include +#include +#include +#include + +#include "LayerBase.h" +#include "LayerBitmap.h" + +namespace android { + +// --------------------------------------------------------------------------- +class OrientationAnimation; + + +class LayerOrientationAnimBase : public LayerBase +{ +public: + LayerOrientationAnimBase(SurfaceFlinger* flinger, DisplayID display) + : LayerBase(flinger, display) { + } + virtual void onOrientationCompleted() = 0; +}; + +// --------------------------------------------------------------------------- + +class LayerOrientationAnim : public LayerOrientationAnimBase +{ +public: + static const uint32_t typeInfo; + static const char* const typeID; + virtual char const* getTypeID() const { return typeID; } + virtual uint32_t getTypeInfo() const { return typeInfo; } + + LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display, + OrientationAnimation* anim, + const sp& bitmapIn, + const sp& bitmapOut); + virtual ~LayerOrientationAnim(); + + void onOrientationCompleted(); + + virtual void onDraw(const Region& clip) const; + virtual Point getPhysicalSize() const; + virtual void validateVisibility(const Transform& globalTransform); + virtual bool needsBlending() const; + virtual bool isSecure() const { return false; } +private: + void drawScaled(float scale, float alphaIn, float alphaOut) const; + + class Lerp { + float in; + float outMinusIn; + public: + Lerp() : in(0), outMinusIn(0) { } + Lerp(float in, float out) : in(in), outMinusIn(out-in) { } + float getIn() const { return in; }; + float getOut() const { return in + outMinusIn; } + void set(float in, float out) { + this->in = in; + this->outMinusIn = out-in; + } + void setIn(float in) { + this->in = in; + } + void setOut(float out) { + this->outMinusIn = out - this->in; + } + float operator()(float t) const { + return outMinusIn*t + in; + } + }; + + OrientationAnimation* mAnim; + sp mBitmapIn; + sp mBitmapOut; + nsecs_t mStartTime; + nsecs_t mFinishTime; + bool mOrientationCompleted; + mutable bool mFirstRedraw; + mutable float mLastNormalizedTime; + mutable GLuint mTextureName; + mutable GLuint mTextureNameIn; + mutable bool mNeedsBlending; + + mutable Lerp mAlphaInLerp; + mutable Lerp mAlphaOutLerp; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_LAYER_ORIENTATION_ANIM_H diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp new file mode 100644 index 000000000000..dc6b632a694d --- /dev/null +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp @@ -0,0 +1,269 @@ +/* + * 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 "SurfaceFlinger" + +#include +#include +#include + +#include +#include + +#include "LayerBase.h" +#include "LayerOrientationAnim.h" +#include "LayerOrientationAnimRotate.h" +#include "SurfaceFlinger.h" +#include "DisplayHardware/DisplayHardware.h" +#include "OrientationAnimation.h" + +namespace android { +// --------------------------------------------------------------------------- + +const uint32_t LayerOrientationAnimRotate::typeInfo = LayerBase::typeInfo | 0x100; +const char* const LayerOrientationAnimRotate::typeID = "LayerOrientationAnimRotate"; + +// --------------------------------------------------------------------------- + +const float ROTATION = M_PI * 0.5f; +const float ROTATION_FACTOR = 1.0f; // 1.0 or 2.0 +const float DURATION = ms2ns(200); +const float BOUNCES_PER_SECOND = 0.8; +const float BOUNCES_AMPLITUDE = (5.0f/180.f) * M_PI; + +LayerOrientationAnimRotate::LayerOrientationAnimRotate( + SurfaceFlinger* flinger, DisplayID display, + OrientationAnimation* anim, + const sp& bitmapIn, + const sp& bitmapOut) + : LayerOrientationAnimBase(flinger, display), mAnim(anim), + mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), + mTextureName(-1), mTextureNameIn(-1) +{ + mStartTime = systemTime(); + mFinishTime = 0; + mOrientationCompleted = false; + mFirstRedraw = false; + mLastNormalizedTime = 0; + mLastAngle = 0; + mLastScale = 0; + mNeedsBlending = false; + const GraphicPlane& plane(graphicPlane(0)); + mOriginalTargetOrientation = plane.getOrientation(); +} + +LayerOrientationAnimRotate::~LayerOrientationAnimRotate() +{ + if (mTextureName != -1U) { + glDeleteTextures(1, &mTextureName); + } + if (mTextureNameIn != -1U) { + glDeleteTextures(1, &mTextureNameIn); + } +} + +bool LayerOrientationAnimRotate::needsBlending() const +{ + return mNeedsBlending; +} + +Point LayerOrientationAnimRotate::getPhysicalSize() const +{ + const GraphicPlane& plane(graphicPlane(0)); + const DisplayHardware& hw(plane.displayHardware()); + return Point(hw.getWidth(), hw.getHeight()); +} + +void LayerOrientationAnimRotate::validateVisibility(const Transform&) +{ + const Layer::State& s(drawingState()); + const Transform tr(s.transform); + const Point size(getPhysicalSize()); + uint32_t w = size.x; + uint32_t h = size.y; + mTransformedBounds = tr.makeBounds(w, h); + mLeft = tr.tx(); + mTop = tr.ty(); + transparentRegionScreen.clear(); + mTransformed = true; +} + +void LayerOrientationAnimRotate::onOrientationCompleted() +{ + mFinishTime = systemTime(); + mOrientationCompleted = true; + mFirstRedraw = true; + mNeedsBlending = true; + mFlinger->invalidateLayerVisibility(this); +} + +void LayerOrientationAnimRotate::onDraw(const Region& clip) const +{ + // Animation... + + const nsecs_t now = systemTime(); + float angle, scale, alpha; + + if (mOrientationCompleted) { + if (mFirstRedraw) { + // make a copy of what's on screen + copybit_image_t image; + mBitmapIn->getBitmapSurface(&image); + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + hw.copyBackToImage(image); + + // FIXME: code below is gross + mFirstRedraw = false; + mNeedsBlending = false; + LayerOrientationAnimRotate* self(const_cast(this)); + mFlinger->invalidateLayerVisibility(self); + } + + // make sure pick-up where we left off + const float duration = DURATION * mLastNormalizedTime; + const float normalizedTime = (float(now - mFinishTime) / duration); + if (normalizedTime <= 1.0f) { + const float squaredTime = normalizedTime*normalizedTime; + angle = (ROTATION*ROTATION_FACTOR - mLastAngle)*squaredTime + mLastAngle; + scale = (1.0f - mLastScale)*squaredTime + mLastScale; + alpha = normalizedTime; + } else { + mAnim->onAnimationFinished(); + angle = ROTATION; + alpha = 1.0f; + scale = 1.0f; + } + } else { + // FIXME: works only for portrait framebuffers + const Point size(getPhysicalSize()); + const float TARGET_SCALE = size.x * (1.0f / size.y); + const float normalizedTime = float(now - mStartTime) / DURATION; + if (normalizedTime <= 1.0f) { + mLastNormalizedTime = normalizedTime; + const float squaredTime = normalizedTime*normalizedTime; + angle = ROTATION * squaredTime; + scale = (TARGET_SCALE - 1.0f)*squaredTime + 1.0f; + alpha = 0; + } else { + mLastNormalizedTime = 1.0f; + angle = ROTATION; + if (BOUNCES_AMPLITUDE) { + const float to_seconds = DURATION / seconds(1); + const float phi = BOUNCES_PER_SECOND * + (((normalizedTime - 1.0f) * to_seconds)*M_PI*2); + angle += BOUNCES_AMPLITUDE * sinf(phi); + } + scale = TARGET_SCALE; + alpha = 0; + } + mLastAngle = angle; + mLastScale = scale; + } + drawScaled(angle, scale, alpha); +} + +void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const +{ + copybit_image_t dst; + const GraphicPlane& plane(graphicPlane(0)); + const DisplayHardware& hw(plane.displayHardware()); + //hw.getDisplaySurface(&dst); + + // clear screen + // TODO: with update on demand, we may be able + // to not erase the screen at all during the animation + glDisable(GL_BLEND); + glDisable(GL_DITHER); + glDisable(GL_SCISSOR_TEST); + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT); + + const int w = dst.w; + const int h = dst.h; + + copybit_image_t src; + mBitmapIn->getBitmapSurface(&src); + const copybit_rect_t srect = { 0, 0, src.w, src.h }; + + + GGLSurface t; + t.version = sizeof(GGLSurface); + t.width = src.w; + t.height = src.h; + t.stride = src.w; + t.vstride= src.h; + t.format = src.format; + t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); + + if (!mOriginalTargetOrientation) { + f = -f; + } + + Transform tr; + tr.set(f, w*0.5f, h*0.5f); + tr.scale(s, w*0.5f, h*0.5f); + + // FIXME: we should not access mVertices and mDrawingState like that, + // but since we control the animation, we know it's going to work okay. + // eventually we'd need a more formal way of doing things like this. + LayerOrientationAnimRotate& self(const_cast(*this)); + tr.transform(self.mVertices[0], 0, 0); + tr.transform(self.mVertices[1], 0, src.h); + tr.transform(self.mVertices[2], src.w, src.h); + tr.transform(self.mVertices[3], src.w, 0); + + if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { + // Too slow to do this in software + self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter; + } + + if (UNLIKELY(mTextureName == -1LU)) { + mTextureName = createTexture(); + GLuint w=0, h=0; + const Region dirty(Rect(t.width, t.height)); + loadTexture(dirty, mTextureName, t, w, h); + } + self.mDrawingState.alpha = 255; //-int(alpha*255); + const Region clip(Rect( srect.l, srect.t, srect.r, srect.b )); + drawWithOpenGL(clip, mTextureName, t); + + if (alpha > 0) { + const float sign = (!mOriginalTargetOrientation) ? 1.0f : -1.0f; + tr.set(f + sign*(M_PI * 0.5f * ROTATION_FACTOR), w*0.5f, h*0.5f); + tr.scale(s, w*0.5f, h*0.5f); + tr.transform(self.mVertices[0], 0, 0); + tr.transform(self.mVertices[1], 0, src.h); + tr.transform(self.mVertices[2], src.w, src.h); + tr.transform(self.mVertices[3], src.w, 0); + + copybit_image_t src; + mBitmapIn->getBitmapSurface(&src); + t.data = (GGLubyte*)(intptr_t(src.base) + src.offset); + if (UNLIKELY(mTextureNameIn == -1LU)) { + mTextureNameIn = createTexture(); + GLuint w=0, h=0; + const Region dirty(Rect(t.width, t.height)); + loadTexture(dirty, mTextureNameIn, t, w, h); + } + self.mDrawingState.alpha = int(alpha*255); + const Region clip(Rect( srect.l, srect.t, srect.r, srect.b )); + drawWithOpenGL(clip, mTextureNameIn, t); + } +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h new file mode 100644 index 000000000000..a675c79b5176 --- /dev/null +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h @@ -0,0 +1,77 @@ +/* + * 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_ORIENTATION_ANIM_ROTATE_H +#define ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H + +#include +#include +#include +#include + +#include "LayerBase.h" +#include "LayerBitmap.h" + +namespace android { + +// --------------------------------------------------------------------------- +class OrientationAnimation; + +class LayerOrientationAnimRotate : public LayerOrientationAnimBase +{ +public: + static const uint32_t typeInfo; + static const char* const typeID; + virtual char const* getTypeID() const { return typeID; } + virtual uint32_t getTypeInfo() const { return typeInfo; } + + LayerOrientationAnimRotate(SurfaceFlinger* flinger, DisplayID display, + OrientationAnimation* anim, + const sp& bitmapIn, + const sp& bitmapOut); + virtual ~LayerOrientationAnimRotate(); + + void onOrientationCompleted(); + + virtual void onDraw(const Region& clip) const; + virtual Point getPhysicalSize() const; + virtual void validateVisibility(const Transform& globalTransform); + virtual bool needsBlending() const; + virtual bool isSecure() const { return false; } +private: + void drawScaled(float angle, float scale, float alpha) const; + + OrientationAnimation* mAnim; + sp mBitmapIn; + sp mBitmapOut; + nsecs_t mStartTime; + nsecs_t mFinishTime; + bool mOrientationCompleted; + int mOriginalTargetOrientation; + mutable bool mFirstRedraw; + mutable float mLastNormalizedTime; + mutable float mLastAngle; + mutable float mLastScale; + mutable GLuint mTextureName; + mutable GLuint mTextureNameIn; + mutable bool mNeedsBlending; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H diff --git a/libs/surfaceflinger/purgatory/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp new file mode 100644 index 000000000000..a6c9c28d0ba8 --- /dev/null +++ b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp @@ -0,0 +1,150 @@ +/* + * 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 "LayerOrientationAnim.h" +#include "LayerOrientationAnimRotate.h" +#include "OrientationAnimation.h" +#include "SurfaceFlinger.h" + +#include "DisplayHardware/DisplayHardware.h" + +namespace android { + +// --------------------------------------------------------------------------- + +OrientationAnimation::OrientationAnimation(const sp& flinger) + : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE) +{ +} + +OrientationAnimation::~OrientationAnimation() +{ +} + +void OrientationAnimation::onOrientationChanged(uint32_t type) +{ + if (mState == DONE) { + mType = type; + if (!(type & ISurfaceComposer::eOrientationAnimationDisable)) { + mState = PREPARE; + } + } +} + +void OrientationAnimation::onAnimationFinished() +{ + if (mState != DONE) + mState = FINISH; +} + +bool OrientationAnimation::run_impl() +{ + bool skip_frame; + switch (mState) { + default: + case DONE: + skip_frame = done(); + break; + case PREPARE: + skip_frame = prepare(); + break; + case PHASE1: + skip_frame = phase1(); + break; + case PHASE2: + skip_frame = phase2(); + break; + case FINISH: + skip_frame = finished(); + break; + } + return skip_frame; +} + +bool OrientationAnimation::done() +{ + return done_impl(); +} + +bool OrientationAnimation::prepare() +{ + mState = PHASE1; + + const GraphicPlane& plane(mFlinger->graphicPlane(0)); + const DisplayHardware& hw(plane.displayHardware()); + const uint32_t w = hw.getWidth(); + const uint32_t h = hw.getHeight(); + + sp bitmap = new Buffer(w, h, hw.getFormat()); + sp bitmapIn = new Buffer(w, h, hw.getFormat()); + + copybit_image_t front; + bitmap->getBitmapSurface(&front); + hw.copyFrontToImage(front); // FIXME: we need an extension to do this + + sp l; + + if (mType & 0x80) { + l = new LayerOrientationAnimRotate( + mFlinger.get(), 0, this, bitmap, bitmapIn); + } else { + l = new LayerOrientationAnim( + mFlinger.get(), 0, this, bitmap, bitmapIn); + } + + l->initStates(w, h, 0); + l->setLayer(INT_MAX-1); + mFlinger->addLayer(l); + mLayerOrientationAnim = l; + return true; +} + +bool OrientationAnimation::phase1() +{ + if (mFlinger->isFrozen() == false) { + // start phase 2 + mState = PHASE2; + mLayerOrientationAnim->onOrientationCompleted(); + mLayerOrientationAnim->invalidate(); + return true; + + } + mLayerOrientationAnim->invalidate(); + return false; +} + +bool OrientationAnimation::phase2() +{ + // do the 2nd phase of the animation + mLayerOrientationAnim->invalidate(); + return false; +} + +bool OrientationAnimation::finished() +{ + mState = DONE; + mFlinger->removeLayer(mLayerOrientationAnim); + mLayerOrientationAnim.clear(); + return true; +} + +// --------------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/surfaceflinger/purgatory/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h new file mode 100644 index 000000000000..8ba66210e873 --- /dev/null +++ b/libs/surfaceflinger/purgatory/OrientationAnimation.h @@ -0,0 +1,84 @@ +/* + * 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_ORIENTATION_ANIMATION_H +#define ANDROID_ORIENTATION_ANIMATION_H + +#include +#include + +#include "SurfaceFlinger.h" + +namespace android { + +// --------------------------------------------------------------------------- + +class SurfaceFlinger; +class MemoryDealer; +class LayerOrientationAnim; + +class OrientationAnimation +{ +public: + OrientationAnimation(const sp& flinger); + virtual ~OrientationAnimation(); + + void onOrientationChanged(uint32_t type); + void onAnimationFinished(); + inline bool run() { + if (LIKELY(mState == DONE)) + return done_impl(); + return run_impl(); + } + +private: + enum { + DONE = 0, + PREPARE, + PHASE1, + PHASE2, + FINISH + }; + + bool run_impl(); + inline bool done_impl() { + if (mFlinger->isFrozen()) { + // we are not allowed to draw, but pause a bit to make sure + // apps don't end up using the whole CPU, if they depend on + // surfaceflinger for synchronization. + usleep(8333); // 8.3ms ~ 120fps + return true; + } + return false; + } + + bool done(); + bool prepare(); + bool phase1(); + bool phase2(); + bool finished(); + + sp mFlinger; + sp< LayerOrientationAnimBase > mLayerOrientationAnim; + int mState; + uint32_t mType; +}; + +// --------------------------------------------------------------------------- + +}; // namespace android + +#endif // ANDROID_ORIENTATION_ANIMATION_H diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 577dd4bf7904..d44d2f965be4 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -5,9 +5,9 @@ LOCAL_SRC_FILES:= \ BufferMapper.cpp \ Camera.cpp \ CameraParameters.cpp \ - EGLNativeWindowSurface.cpp \ EventHub.cpp \ EventRecurrence.cpp \ + FramebufferNativeWindow.cpp \ KeyLayoutMap.cpp \ KeyCharacterMap.cpp \ ICamera.cpp \ diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index 85a029bcc0d2..1a75c5d9acdf 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -17,14 +17,9 @@ #define LOG_TAG "BufferMapper" #include -#include -#include #include -#include -#include #include -#include #include #include @@ -34,12 +29,6 @@ #include -// --------------------------------------------------------------------------- -// enable mapping debugging -#define DEBUG_MAPPINGS 0 -// never remove mappings from the list -#define DEBUG_MAPPINGS_KEEP_ALL 0 -// --------------------------------------------------------------------------- namespace android { // --------------------------------------------------------------------------- @@ -57,34 +46,27 @@ BufferMapper::BufferMapper() } } -status_t BufferMapper::map(buffer_handle_t handle, void** addr, const void* id) +status_t BufferMapper::registerBuffer(buffer_handle_t handle) { - Mutex::Autolock _l(mLock); - status_t err = mAllocMod->map(mAllocMod, handle, addr); - LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); -#if DEBUG_MAPPINGS - if (err == NO_ERROR) - logMapLocked(handle, id); -#endif + status_t err = mAllocMod->registerBuffer(mAllocMod, handle); + LOGW_IF(err, "registerBuffer(%p) failed %d (%s)", + handle, err, strerror(-err)); return err; } -status_t BufferMapper::unmap(buffer_handle_t handle, const void* id) +status_t BufferMapper::unregisterBuffer(buffer_handle_t handle) { - Mutex::Autolock _l(mLock); - status_t err = mAllocMod->unmap(mAllocMod, handle); - LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); -#if DEBUG_MAPPINGS - if (err == NO_ERROR) - logUnmapLocked(handle, id); -#endif + 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) +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()); + bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr); LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err)); return err; } @@ -96,65 +78,5 @@ status_t BufferMapper::unlock(buffer_handle_t handle) return err; } -void BufferMapper::logMapLocked(buffer_handle_t handle, const void* id) -{ - CallStack stack; - stack.update(2); - - map_info_t info; - info.id = id; - info.stack = stack; - - ssize_t index = mMapInfo.indexOfKey(handle); - if (index >= 0) { - Vector& infos = mMapInfo.editValueAt(index); - infos.add(info); - } else { - Vector infos; - infos.add(info); - mMapInfo.add(handle, infos); - } -} - -void BufferMapper::logUnmapLocked(buffer_handle_t handle, const void* id) -{ - ssize_t index = mMapInfo.indexOfKey(handle); - if (index < 0) { - LOGE("unmapping %p which doesn't exist in our map!", handle); - return; - } - - Vector& infos = mMapInfo.editValueAt(index); - ssize_t count = infos.size(); - for (int i=0 ; i& infos = mMapInfo.valueAt(index); - ssize_t count = infos.size(); - for (int i=0 ; i -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -/* - * This implements the (main) framebuffer management. This class is used - * mostly by SurfaceFlinger, but also by command line GL application. - * - * In fact this is an implementation of android_native_window_t on top of - * the framebuffer. - * - * Currently it is pretty simple, it manages only two buffers (the front and - * back buffer). - * - */ - -FramebufferNativeWindow::FramebufferNativeWindow() - : BASE(), fbDev(0), grDev(0) -{ - hw_module_t const* module; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { - int stride; - framebuffer_open(module, &fbDev); - gralloc_open(module, &grDev); - int err; - - - // initialize the buffer FIFO - mNumBuffers = 2; - mNumFreeBuffers = 2; - mBufferHead = mNumBuffers-1; - buffers[0] = new NativeBuffer( - fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); - buffers[1] = new NativeBuffer( - fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); - - err = grDev->alloc(grDev, - fbDev->width, fbDev->height, fbDev->format, - GRALLOC_USAGE_HW_FB, &buffers[0]->handle, &buffers[0]->stride); - - LOGE_IF(err, "fb buffer 0 allocation failed w=%d, h=%d, err=%s", - fbDev->width, fbDev->height, strerror(-err)); - - err = grDev->alloc(grDev, - fbDev->width, fbDev->height, fbDev->format, - GRALLOC_USAGE_HW_FB, &buffers[1]->handle, &buffers[1]->stride); - - LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s", - fbDev->width, fbDev->height, strerror(-err)); - - gralloc_module_t* m = - reinterpret_cast(grDev->common.module); - - // FIXME: do we actually need to map the framebuffer? - m->map(m, buffers[0]->handle, &buffers[0]->bits); - m->map(m, buffers[1]->handle, &buffers[1]->bits); - } - - uint32_t flags = fbDev->flags & SURFACE_FLAG_MAPPED; - - /* - * FIXME: SURFACE_FLAG_PRESERVE_CONTENT - * how to implement this, there is no concept of preserve content in - * the framebuffer, which just "posts" buffer. - * - * It looks like what we need is a way to know if the posted buffer can - * be reused. But if so, why allocating 2 buffers?... - * - * should the lock/unlock calls take care of the copy-back? - * - * - * In the end, the client wants to know if the backbuffer is preserved - * though... it's complicated. - * - */ - - //flags |= SURFACE_FLAG_PRESERVE_CONTENT; - - - const_cast(android_native_window_t::flags) = flags; - const_cast(android_native_window_t::xdpi) = fbDev->xdpi; - const_cast(android_native_window_t::ydpi) = fbDev->ydpi; - const_cast(android_native_window_t::minSwapInterval) = - fbDev->minSwapInterval; - const_cast(android_native_window_t::maxSwapInterval) = - fbDev->maxSwapInterval; - - android_native_window_t::connect = connect; - android_native_window_t::disconnect = disconnect; - android_native_window_t::setSwapInterval = setSwapInterval; - android_native_window_t::setSwapRectangle = setSwapRectangle; - android_native_window_t::dequeueBuffer = dequeueBuffer; - android_native_window_t::lockBuffer = lockBuffer; - android_native_window_t::queueBuffer = queueBuffer; -} - -FramebufferNativeWindow::~FramebufferNativeWindow() { - grDev->free(grDev, buffers[0]->handle); - grDev->free(grDev, buffers[1]->handle); - gralloc_module_t* m = - reinterpret_cast(grDev->common.module); - m->unmap(m, buffers[0]->handle); - m->unmap(m, buffers[1]->handle); - gralloc_close(grDev); - framebuffer_close(fbDev); -} - -void FramebufferNativeWindow::connect(android_native_window_t* window) -{ -} - -void FramebufferNativeWindow::disconnect(android_native_window_t* window) -{ -} - -int FramebufferNativeWindow::setSwapInterval( - android_native_window_t* window, int interval) -{ - framebuffer_device_t* fb = getSelf(window)->fbDev; - return fb->setSwapInterval(fb, interval); -} - -int FramebufferNativeWindow::setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h) -{ - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - self->mDirty = Rect(l, t, l+w, t+h); - return 0; -} - -int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, - android_native_buffer_t** buffer) -{ - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - framebuffer_device_t* fb = self->fbDev; - - // wait for a free buffer - while (!self->mNumFreeBuffers) { - self->mCondition.wait(self->mutex); - } - // get this buffer - self->mNumFreeBuffers--; - int index = self->mBufferHead++; - if (self->mBufferHead >= self->mNumBuffers) - self->mBufferHead = 0; - - *buffer = self->buffers[index].get(); - - return 0; -} - -int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, - android_native_buffer_t* buffer) -{ - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - - // wait that the buffer we're locking is not front anymore - while (self->front == buffer) { - self->mCondition.wait(self->mutex); - } - - gralloc_module_t* m = - reinterpret_cast(self->grDev->common.module); - const Rect& dirty(self->mDirty); - - buffer_handle_t handle = static_cast(buffer)->handle; - int res = m->lock(m, handle, GRALLOC_USAGE_HW_FB, - dirty.left, dirty.right, dirty.width(), dirty.height()); - - return res; -} - -int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, - android_native_buffer_t* buffer) -{ - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - framebuffer_device_t* fb = self->fbDev; - gralloc_module_t* m = - reinterpret_cast(self->grDev->common.module); - - buffer_handle_t handle = static_cast(buffer)->handle; - m->unlock(m, handle); - int res = fb->post(fb, handle); - - self->front = static_cast(buffer); - self->mNumFreeBuffers++; - self->mCondition.broadcast(); - return res; -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- - - -EGLNativeWindowType android_createDisplaySurface(void) -{ - return new android::FramebufferNativeWindow(); -} - diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp new file mode 100644 index 000000000000..407d6f4f2b19 --- /dev/null +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -0,0 +1,214 @@ +/* +** +** Copyright 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 "FramebufferNativeWindow" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +/* + * This implements the (main) framebuffer management. This class is used + * mostly by SurfaceFlinger, but also by command line GL application. + * + * In fact this is an implementation of android_native_window_t on top of + * the framebuffer. + * + * Currently it is pretty simple, it manages only two buffers (the front and + * back buffer). + * + */ + +FramebufferNativeWindow::FramebufferNativeWindow() + : BASE(), fbDev(0), grDev(0) +{ + hw_module_t const* module; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { + int stride; + framebuffer_open(module, &fbDev); + gralloc_open(module, &grDev); + int err; + + + // initialize the buffer FIFO + mNumBuffers = 2; + mNumFreeBuffers = 2; + mBufferHead = mNumBuffers-1; + buffers[0] = new NativeBuffer( + fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); + buffers[1] = new NativeBuffer( + fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); + + err = grDev->alloc(grDev, + fbDev->width, fbDev->height, fbDev->format, + GRALLOC_USAGE_HW_FB, &buffers[0]->handle, &buffers[0]->stride); + + LOGE_IF(err, "fb buffer 0 allocation failed w=%d, h=%d, err=%s", + fbDev->width, fbDev->height, strerror(-err)); + + err = grDev->alloc(grDev, + fbDev->width, fbDev->height, fbDev->format, + GRALLOC_USAGE_HW_FB, &buffers[1]->handle, &buffers[1]->stride); + + LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s", + fbDev->width, fbDev->height, strerror(-err)); + } + + uint32_t flags = fbDev->flags & SURFACE_FLAG_MAPPED; + + /* + * FIXME: SURFACE_FLAG_PRESERVE_CONTENT + * how to implement this, there is no concept of preserve content in + * the framebuffer, which just "posts" buffer. + * + * It looks like what we need is a way to know if the posted buffer can + * be reused. But if so, why allocating 2 buffers?... + * + * should the lock/unlock calls take care of the copy-back? + * + * + * In the end, the client wants to know if the backbuffer is preserved + * though... it's complicated. + * + */ + + //flags |= SURFACE_FLAG_PRESERVE_CONTENT; + + + const_cast(android_native_window_t::flags) = flags; + const_cast(android_native_window_t::xdpi) = fbDev->xdpi; + const_cast(android_native_window_t::ydpi) = fbDev->ydpi; + const_cast(android_native_window_t::minSwapInterval) = + fbDev->minSwapInterval; + const_cast(android_native_window_t::maxSwapInterval) = + fbDev->maxSwapInterval; + + android_native_window_t::setSwapInterval = setSwapInterval; + android_native_window_t::dequeueBuffer = dequeueBuffer; + android_native_window_t::lockBuffer = lockBuffer; + android_native_window_t::queueBuffer = queueBuffer; +} + +FramebufferNativeWindow::~FramebufferNativeWindow() { + grDev->free(grDev, buffers[0]->handle); + grDev->free(grDev, buffers[1]->handle); + gralloc_close(grDev); + framebuffer_close(fbDev); +} + +void FramebufferNativeWindow::connect(android_native_window_t* window) +{ +} + +void FramebufferNativeWindow::disconnect(android_native_window_t* window) +{ +} + +int FramebufferNativeWindow::setSwapInterval( + android_native_window_t* window, int interval) +{ + framebuffer_device_t* fb = getSelf(window)->fbDev; + return fb->setSwapInterval(fb, interval); +} + +void FramebufferNativeWindow::setSwapRectangle(const Rect& dirty) +{ + Mutex::Autolock _l(mutex); + mDirty = dirty; +} + +int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, + android_native_buffer_t** buffer) +{ + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + framebuffer_device_t* fb = self->fbDev; + + // wait for a free buffer + while (!self->mNumFreeBuffers) { + self->mCondition.wait(self->mutex); + } + // get this buffer + self->mNumFreeBuffers--; + int index = self->mBufferHead++; + if (self->mBufferHead >= self->mNumBuffers) + self->mBufferHead = 0; + + *buffer = self->buffers[index].get(); + + return 0; +} + +int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, + android_native_buffer_t* buffer) +{ + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + + // wait that the buffer we're locking is not front anymore + while (self->front == buffer) { + self->mCondition.wait(self->mutex); + } + + return NO_ERROR; +} + +int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, + android_native_buffer_t* buffer) +{ + FramebufferNativeWindow* self = getSelf(window); + Mutex::Autolock _l(self->mutex); + framebuffer_device_t* fb = self->fbDev; + buffer_handle_t handle = static_cast(buffer)->handle; + int res = fb->post(fb, handle); + self->front = static_cast(buffer); + self->mNumFreeBuffers++; + self->mCondition.broadcast(); + return res; +} + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + + +EGLNativeWindowType android_createDisplaySurface(void) +{ + return new android::FramebufferNativeWindow(); +} + diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 26e694a70ad5..30da911fc72c 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -88,6 +88,13 @@ void Region::set(const Rect& r) mRegion.setRect(ir); } +void Region::set(uint32_t w, uint32_t h) +{ + SkIRect ir; + ir.set(0, 0, w, h); + mRegion.setRect(ir); +} + // ---------------------------------------------------------------------------- Region& Region::orSelf(const Rect& r) diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index fb105b346c7e..68fd9632cc12 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -31,7 +31,6 @@ #include #include -#include #include #include #include @@ -53,7 +52,7 @@ namespace android { ANDROID_SINGLETON_STATIC_INSTANCE( SurfaceBuffer ) SurfaceBuffer::SurfaceBuffer() - : BASE(), handle(0), mOwner(false) + : BASE(), handle(0), mOwner(false), mBufferMapper(BufferMapper::get()) { width = height = @@ -64,7 +63,7 @@ SurfaceBuffer::SurfaceBuffer() } SurfaceBuffer::SurfaceBuffer(const Parcel& data) - : BASE(), handle(0), mOwner(true) + : BASE(), handle(0), mOwner(true), mBufferMapper(BufferMapper::get()) { // we own the handle in this case width = data.readInt32(); @@ -91,6 +90,26 @@ int SurfaceBuffer::getHandle(android_native_buffer_t const * base, return 0; } +status_t SurfaceBuffer::lock(uint32_t usage) +{ + const Rect lockBounds(width, height); + status_t res = lock(usage, lockBounds); + return res; +} + +status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect) +{ + status_t res = getBufferMapper().lock(handle, usage, rect, &bits); + return res; +} + +status_t SurfaceBuffer::unlock() +{ + status_t res = getBufferMapper().unlock(handle); + bits = NULL; + return res; +} + status_t SurfaceBuffer::writeToParcel(Parcel* reply, android_native_buffer_t const* buffer) { @@ -110,9 +129,17 @@ status_t SurfaceBuffer::writeToParcel(Parcel* reply, // ---------------------------------------------------------------------- -static void copyBlt(const android_native_buffer_t* dst, - const android_native_buffer_t* src, const Region& reg) +static void copyBlt( + const sp& dst, + const sp& src, + const Region& reg) { + src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds()); + uint8_t const * const src_bits = (uint8_t const *)src->bits; + + dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds()); + uint8_t* const dst_bits = (uint8_t*)dst->bits; + Region::iterator iterator(reg); if (iterator) { // NOTE: dst and src must be the same format @@ -120,29 +147,29 @@ static void copyBlt(const android_native_buffer_t* dst, const size_t bpp = bytesPerPixel(src->format); const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; + while (iterator.iterate(&r)) { - ssize_t h = r.bottom - r.top; - if (h) { - size_t size = (r.right - r.left) * bpp; - uint8_t* s = (GGLubyte*)src->bits + - (r.left + src->stride * r.top) * bpp; - uint8_t* d = (GGLubyte*)dst->bits + - (r.left + dst->stride * r.top) * bpp; - if (dbpr==sbpr && size==sbpr) { - size *= h; - h = 1; - } - do { - memcpy(d, s, size); - d += dbpr; - s += sbpr; - } while (--h > 0); + ssize_t h = r.height(); + if (h <= 0) continue; + size_t size = r.width() * bpp; + uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp; + uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp; + if (dbpr==sbpr && size==sbpr) { + size *= h; + h = 1; } + do { + memcpy(d, s, size); + d += dbpr; + s += sbpr; + } while (--h > 0); } } + + src->unlock(); + dst->unlock(); } - // ============================================================================ // SurfaceControl // ============================================================================ @@ -347,12 +374,14 @@ sp SurfaceControl::getSurface() const Surface::Surface(const sp& surface) : mClient(surface->mClient), mSurface(surface->mSurface), mToken(surface->mToken), mIdentity(surface->mIdentity), - mFormat(surface->mFormat), mFlags(surface->mFlags) + mFormat(surface->mFormat), mFlags(surface->mFlags), + mBufferMapper(BufferMapper::get()) { init(); } Surface::Surface(const Parcel& parcel) + : mBufferMapper(BufferMapper::get()) { sp clientBinder = parcel.readStrongBinder(); mSurface = interface_cast(parcel.readStrongBinder()); @@ -369,16 +398,11 @@ Surface::Surface(const Parcel& parcel) void Surface::init() { - android_native_window_t::connect = connect; - android_native_window_t::disconnect = disconnect; android_native_window_t::setSwapInterval = setSwapInterval; - android_native_window_t::setSwapRectangle = setSwapRectangle; android_native_window_t::dequeueBuffer = dequeueBuffer; android_native_window_t::lockBuffer = lockBuffer; android_native_window_t::queueBuffer = queueBuffer; - mSwapRectangle.makeInvalid(); - DisplayInfo dinfo; SurfaceComposerClient::getDisplayInfo(0, &dinfo); const_cast(android_native_window_t::xdpi) = dinfo.xdpi; @@ -396,7 +420,7 @@ Surface::~Surface() // its buffers in this process. for (int i=0 ; i<2 ; i++) { if (mBuffers[i] != 0) { - BufferMapper::get().unmap(mBuffers[i]->getHandle(), this); + getBufferMapper().unregisterBuffer(mBuffers[i]->getHandle()); } } @@ -443,22 +467,6 @@ bool Surface::isSameSurface( // ---------------------------------------------------------------------------- -int Surface::setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h) -{ - Surface* self = getSelf(window); - self->setSwapRectangle(Rect(l, t, l+w, t+h)); - return 0; -} - -void Surface::connect(android_native_window_t* window) -{ -} - -void Surface::disconnect(android_native_window_t* window) -{ -} - int Surface::setSwapInterval(android_native_window_t* window, int interval) { return 0; @@ -487,6 +495,26 @@ int Surface::queueBuffer(android_native_window_t* window, // ---------------------------------------------------------------------------- +status_t Surface::dequeueBuffer(sp* buffer) +{ + android_native_buffer_t* out; + status_t err = dequeueBuffer(&out); + *buffer = SurfaceBuffer::getSelf(out); + return err; +} + +status_t Surface::lockBuffer(const sp& buffer) +{ + return lockBuffer(buffer.get()); +} + +status_t Surface::queueBuffer(const sp& buffer) +{ + return queueBuffer(buffer.get()); +} + +// ---------------------------------------------------------------------------- + int Surface::dequeueBuffer(android_native_buffer_t** buffer) { // FIXME: dequeueBuffer() needs proper implementation @@ -515,8 +543,9 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer) } const sp& backBuffer(mBuffers[backIdx]); + mDirtyRegion.set(backBuffer->width, backBuffer->height); *buffer = backBuffer.get(); - + return NO_ERROR; } @@ -542,11 +571,14 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) if (err != NO_ERROR) return err; + if (mSwapRectangle.isValid()) { + mDirtyRegion.set(mSwapRectangle); + } + // transmit the dirty region - const Region dirty(swapRectangle()); SurfaceID index(mToken); layer_cblk_t* const lcblk = &(cblk->layers[index]); - _send_dirty_region(lcblk, dirty); + _send_dirty_region(lcblk, mDirtyRegion); uint32_t newstate = cblk->unlock_layer_and_post(size_t(index)); if (!(newstate & eNextFlipPending)) @@ -561,27 +593,20 @@ status_t Surface::lock(SurfaceInfo* info, bool blocking) { return Surface::lock(info, NULL, blocking); } -status_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) +status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) { // FIXME: needs some locking here - android_native_buffer_t* backBuffer; + + sp backBuffer; status_t err = dequeueBuffer(&backBuffer); if (err == NO_ERROR) { err = lockBuffer(backBuffer); if (err == NO_ERROR) { - backBuffer->common.incRef(&backBuffer->common); - mLockedBuffer = backBuffer; - other->w = backBuffer->width; - other->h = backBuffer->height; - other->s = backBuffer->stride; - other->usage = backBuffer->usage; - other->format = backBuffer->format; - other->bits = backBuffer->bits; - // we handle copy-back here... const Rect bounds(backBuffer->width, backBuffer->height); - Region newDirtyRegion; + Region scratch(bounds); + Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch); per_client_cblk_t* const cblk = mClient->mControl; layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]); @@ -590,43 +615,34 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) // content is meaningless in this case and the whole surface // needs to be redrawn. newDirtyRegion.set(bounds); - if (dirty) { - *dirty = newDirtyRegion; - } - } else - { - if (dirty) { - dirty->andSelf(Region(bounds)); - newDirtyRegion = *dirty; - } else { - newDirtyRegion.set(bounds); - } - Region copyback; + } else { + newDirtyRegion.andSelf(bounds); if (!(lcblk->flags & eNoCopyBack)) { - const Region previousDirtyRegion(dirtyRegion()); - copyback = previousDirtyRegion.subtract(newDirtyRegion); - } - const sp& frontBuffer(mBuffers[1-mBackbufferIndex]); - if (!copyback.isEmpty() && frontBuffer!=0) { - // copy front to back - copyBlt(backBuffer, frontBuffer.get(), copyback); + const sp& frontBuffer(mBuffers[1-mBackbufferIndex]); + const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion)); + if (!copyback.isEmpty() && frontBuffer!=0) { + // copy front to back + copyBlt(backBuffer, frontBuffer, copyback); + } } } - setDirtyRegion(newDirtyRegion); - + mDirtyRegion = newDirtyRegion; + mOldDirtyRegion = newDirtyRegion; - Rect lockBounds(backBuffer->width, backBuffer->height); - if (dirty) { - lockBounds = dirty->bounds(); - } - buffer_handle_t handle; - backBuffer->getHandle(backBuffer, &handle); - status_t res = BufferMapper::get().lock(handle, - GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - lockBounds); + status_t res = backBuffer->lock( + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + newDirtyRegion.bounds()); + LOGW_IF(res, "failed locking buffer %d (%p)", - mBackbufferIndex, handle); - setSwapRectangle(lockBounds); + mBackbufferIndex, backBuffer->handle); + + mLockedBuffer = backBuffer; + other->w = backBuffer->width; + other->h = backBuffer->height; + other->s = backBuffer->stride; + other->usage = backBuffer->usage; + other->format = backBuffer->format; + other->bits = backBuffer->bits; } } return err; @@ -639,16 +655,12 @@ status_t Surface::unlockAndPost() if (mLockedBuffer == 0) return BAD_VALUE; - buffer_handle_t handle; - mLockedBuffer->getHandle(mLockedBuffer, &handle); - status_t res = BufferMapper::get().unlock(handle); + status_t res = mLockedBuffer->unlock(); LOGW_IF(res, "failed unlocking buffer %d (%p)", - mBackbufferIndex, handle); - - const Rect dirty(dirtyRegion().bounds()); - setSwapRectangle(dirty); + mBackbufferIndex, mLockedBuffer->handle); + status_t err = queueBuffer(mLockedBuffer); - mLockedBuffer->common.decRef(&mLockedBuffer->common); + mLockedBuffer->bits = NULL; mLockedBuffer = 0; return err; } @@ -666,15 +678,6 @@ void Surface::_send_dirty_region( } } -Region Surface::dirtyRegion() const { - return mDirtyRegion; -} -void Surface::setDirtyRegion(const Region& region) const { - mDirtyRegion = region; -} -const Rect& Surface::swapRectangle() const { - return mSwapRectangle; -} void Surface::setSwapRectangle(const Rect& r) { mSwapRectangle = r; } @@ -687,10 +690,10 @@ status_t Surface::getBufferLocked(int index) if (buffer != 0) { sp& currentBuffer(mBuffers[index]); if (currentBuffer != 0) { - BufferMapper::get().unmap(currentBuffer->getHandle(), this); + getBufferMapper().unregisterBuffer(currentBuffer->getHandle()); currentBuffer.clear(); } - err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits, this); + err = getBufferMapper().registerBuffer(buffer->getHandle()); LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); if (err == NO_ERROR) { currentBuffer = buffer; diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h index e3c3b86e49f4..329705b65a8c 100644 --- a/opengl/include/EGL/android_natives.h +++ b/opengl/include/EGL/android_natives.h @@ -96,18 +96,6 @@ struct android_native_window_t /* Some storage reserved for the OEM's driver. */ intptr_t oem[4]; - /* - * hook called by EGL when the native surface is made current - * (eglMakeCurrent()). This hook can be NULL. - */ - void (*connect)(struct android_native_window_t* window); - - /* - * hook called by EGL when the native surface in not current any-longer. - * This hook can be NULL. - */ - void (*disconnect)(struct android_native_window_t* window); - /* * Set the swap interval for this surface. @@ -117,20 +105,10 @@ struct android_native_window_t int (*setSwapInterval)(struct android_native_window_t* window, int interval); - - /* - * FIXME: needs documentation for setSwapRectangle - * tentative: rect used during queueBuffer to indicate which part of - * the screen needs updating. - */ - int (*setSwapRectangle)(struct android_native_window_t* window, - int left, int top, int width, int height); - - /* * hook called by EGL to acquire a buffer. After this call, the buffer * is not locked, so its content cannot be modified. - * this call may block if no buffers are availlable. + * this call may block if no buffers are available. * * Returns 0 on success or -errno on error. */ @@ -179,7 +157,7 @@ struct android_native_buffer_t int stride; int format; int usage; - void* bits; // non-zero if buffer is mmaped + void* bits; // non-zero if buffer is locked for sw usage void* reserved[2]; diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index f927de95ecae..9eb99f0bc231 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -23,7 +23,7 @@ namespace android { // ---------------------------------------------------------------------------- EGLTextureObject::EGLTextureObject() - : mCount(0), mSize(0) + : mSize(0) { init(); } @@ -56,6 +56,7 @@ void EGLTextureObject::init() #ifdef LIBAGL_USE_GRALLOC_COPYBITS copybits_fd = -1; #endif // LIBAGL_USE_GRALLOC_COPYBITS + buffer = 0; } void EGLTextureObject::copyParameters(const sp& old) @@ -126,6 +127,7 @@ status_t EGLTextureObject::setSurface(GGLSurface const* s) } surface = *s; internalformat = 0; + buffer = 0; // we should keep the crop_rect, but it's delicate because // the new size of the surface could make it invalid. @@ -144,6 +146,20 @@ status_t EGLTextureObject::setSurface(GGLSurface const* s) return NO_ERROR; } +status_t EGLTextureObject::setImage(android_native_buffer_t* native_buffer) +{ + GGLSurface sur; + sur.version = sizeof(GGLSurface); + sur.width = native_buffer->width; + sur.height= native_buffer->height; + sur.stride= native_buffer->stride; + sur.format= native_buffer->format; + sur.data = 0; + setSurface(&sur); + buffer = native_buffer; + return NO_ERROR; +} + status_t EGLTextureObject::reallocate( GLint level, int w, int h, int s, int format, int compressedFormat, int bpr) @@ -227,7 +243,7 @@ status_t EGLTextureObject::reallocate( // ---------------------------------------------------------------------------- EGLSurfaceManager::EGLSurfaceManager() - : TokenManager(), mCount(0) + : TokenManager() { } diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 497528c76b0e..29d50370eb41 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -30,6 +30,7 @@ #include #include +#include #include "Tokenizer.h" #include "TokenManager.h" @@ -39,22 +40,20 @@ namespace android { // ---------------------------------------------------------------------------- -class EGLTextureObject +class EGLTextureObject : public LightRefBase { public: EGLTextureObject(); ~EGLTextureObject(); - // protocol for sp<> - inline void incStrong(const void* id) const; - inline void decStrong(const void* id) const; - inline uint32_t getStrongCount() const; + status_t setSurface(GGLSurface const* s); + status_t setImage(android_native_buffer_t* buffer); + void setImageBits(void* vaddr) { surface.data = (GGLubyte*)vaddr; } - status_t setSurface(GGLSurface const* s); status_t reallocate(GLint level, int w, int h, int s, int format, int compressedFormat, int bpr); - inline size_t size() const; + inline size_t size() const { return mSize; } const GGLSurface& mip(int lod) const; GGLSurface& editMip(int lod); bool hasMipmaps() const { return mMipmaps!=0; } @@ -65,7 +64,6 @@ private: status_t allocateMipmaps(); void freeMipmaps(); void init(); - mutable int32_t mCount; size_t mSize; GGLSurface *mMipmaps; int mNumExtraLod; @@ -84,36 +82,19 @@ public: #ifdef LIBAGL_USE_GRALLOC_COPYBITS int copybits_fd; #endif // LIBAGL_USE_GRALLOC_COPYBITS + android_native_buffer_t* buffer; }; -void EGLTextureObject::incStrong(const void* id) const { - android_atomic_inc(&mCount); -} -void EGLTextureObject::decStrong(const void* id) const { - if (android_atomic_dec(&mCount) == 1) { - delete this; - } -} -uint32_t EGLTextureObject::getStrongCount() const { - return mCount; -} -size_t EGLTextureObject::size() const { - return mSize; -} - // ---------------------------------------------------------------------------- -class EGLSurfaceManager : public TokenManager +class EGLSurfaceManager : + public LightRefBase, + public TokenManager { public: EGLSurfaceManager(); ~EGLSurfaceManager(); - // protocol for sp<> - inline void incStrong(const void* id) const; - inline void decStrong(const void* id) const; - typedef void weakref_type; - sp createTexture(GLuint name); sp removeTexture(GLuint name); sp replaceTexture(GLuint name); @@ -121,21 +102,10 @@ public: sp texture(GLuint name); private: - mutable int32_t mCount; mutable Mutex mLock; KeyedVector< GLuint, sp > mTextures; }; -void EGLSurfaceManager::incStrong(const void* id) const { - android_atomic_inc(&mCount); -} -void EGLSurfaceManager::decStrong(const void* id) const { - if (android_atomic_dec(&mCount) == 1) { - delete this; - } -} - - // ---------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp index eefe614c2fb7..6d2cc9111c84 100644 --- a/opengl/libagl/array.cpp +++ b/opengl/libagl/array.cpp @@ -1371,9 +1371,18 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK)) return; // all triangles are culled + validate_arrays(c, mode); + + const uint32_t enables = c->rasterizer.state.enables; + if (enables & GGL_ENABLE_TMUS) + ogles_lock_textures(c); + drawArraysPrims[mode](c, first, count); + if (enables & GGL_ENABLE_TMUS) + ogles_unlock_textures(c); + #if VC_CACHE_STATISTICS c->vc.total = count; c->vc.dump_stats(mode); @@ -1425,8 +1434,16 @@ void glDrawElements( indices = c->arrays.element_array_buffer->data + uintptr_t(indices); } + const uint32_t enables = c->rasterizer.state.enables; + if (enables & GGL_ENABLE_TMUS) + ogles_lock_textures(c); + drawElementsPrims[mode](c, count, indices); + + if (enables & GGL_ENABLE_TMUS) + ogles_unlock_textures(c); + #if VC_CACHE_STATISTICS c->vc.total = count; c->vc.dump_stats(mode); diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 9384e18dad1d..04ca431778c2 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -212,8 +212,11 @@ struct egl_window_surface_v2_t : public egl_surface_t virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; private: + status_t lock(android_native_buffer_t* buf, int usage); + status_t unlock(android_native_buffer_t* buf); android_native_window_t* nativeWindow; android_native_buffer_t* buffer; + gralloc_module_t const* module; int width; int height; }; @@ -222,8 +225,13 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat, android_native_window_t* window) - : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0) + : egl_surface_t(dpy, config, depthFormat), + nativeWindow(window), buffer(0), module(0) { + hw_module_t const* pModule; + hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); + module = reinterpret_cast(pModule); + nativeWindow->common.incRef(&nativeWindow->common); nativeWindow->dequeueBuffer(nativeWindow, &buffer); @@ -246,13 +254,44 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, buffer->common.incRef(&buffer->common); nativeWindow->lockBuffer(nativeWindow, buffer); - // FIXME: we need to gralloc lock the buffer + // Lock the buffer + lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); + // FIXME: we need to handle the copy-back if needed, but // for now we're a "non preserving" implementation. } +status_t egl_window_surface_v2_t::lock( + android_native_buffer_t* buf, int usage) +{ + int err; + buffer_handle_t bufferHandle; + err = buf->getHandle(buf, &bufferHandle); + if (err < 0) + return err; + + err = module->lock(module, bufferHandle, + usage, 0, 0, buf->width, buf->height, &buf->bits); + return err; +} + +status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) +{ + int err; + buffer_handle_t bufferHandle; + err = buf->getHandle(buf, &bufferHandle); + if (err < 0) + return err; + + err = module->unlock(module, bufferHandle); + buf->bits = NULL; + return err; +} + + egl_window_surface_v2_t::~egl_window_surface_v2_t() { if (buffer) { + unlock(buffer); buffer->common.decRef(&buffer->common); } nativeWindow->common.decRef(&nativeWindow->common); @@ -269,6 +308,7 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() //mDisplaySurface->copyFrontToBack(copyback); + unlock(buffer); nativeWindow->queueBuffer(nativeWindow, buffer); buffer->common.decRef(&buffer->common); buffer = 0; @@ -278,6 +318,7 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() // TODO: lockBuffer should rather be executed when the very first // direct rendering occurs. nativeWindow->lockBuffer(nativeWindow, buffer); + lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); if ((width != buffer->width) || (height != buffer->height)) { @@ -1690,20 +1731,6 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, if (native_buffer->common.version != sizeof(android_native_buffer_t)) return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - - hw_module_t const* pModule; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) - return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - buffer_handle_t bufferHandle; - gralloc_module_t const* module = - reinterpret_cast(pModule); - if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0) - return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - int err = module->map(module, bufferHandle, &native_buffer->bits); - if (err < 0) { - LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err)); - return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); - } native_buffer->common.incRef(&native_buffer->common); return (EGLImageKHR)native_buffer; @@ -1723,18 +1750,6 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) if (native_buffer->common.version != sizeof(android_native_buffer_t)) return setError(EGL_BAD_PARAMETER, EGL_FALSE); - hw_module_t const* pModule; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule) == 0) { - buffer_handle_t bufferHandle; - gralloc_module_t const* module = - reinterpret_cast(pModule); - int err = native_buffer->getHandle(native_buffer, &bufferHandle); - if (err == 0) { - int err = module->unmap(module, bufferHandle); - LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err)); - } - } - native_buffer->common.decRef(&native_buffer->common); return EGL_TRUE; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 9dca1338c2fb..f2d8da3ca259 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -103,7 +103,7 @@ void validate_tmu(ogles_context_t* c, int i) } } -void ogles_validate_texture_impl(ogles_context_t* c) +void ogles_validate_texture(ogles_context_t* c) { for (int i=0 ; irasterizer.state.texture[i].enable) @@ -117,6 +117,67 @@ void invalidate_texture(ogles_context_t* c, int tmu, uint8_t flags = 0xFF) { c->textures.tmu[tmu].dirty = flags; } +/* + * If the active textures are EGLImage, they need to be locked before + * they can be used. + * + * FIXME: code below is far from being optimal + * + */ + +void ogles_lock_textures(ogles_context_t* c) +{ + for (int i=0 ; irasterizer.state.texture[i].enable) { + texture_unit_t& u(c->textures.tmu[i]); + android_native_buffer_t* native_buffer = u.texture->buffer; + if (native_buffer) { + c->rasterizer.procs.activeTexture(c, i); + hw_module_t const* pModule; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) + continue; + + gralloc_module_t const* module = + reinterpret_cast(pModule); + buffer_handle_t bufferHandle; + native_buffer->getHandle(native_buffer, &bufferHandle); + int err = module->lock(module, bufferHandle, + GRALLOC_USAGE_SW_READ_OFTEN, + 0, 0, native_buffer->width, native_buffer->height, + &native_buffer->bits); + + u.texture->setImageBits(native_buffer->bits); + c->rasterizer.procs.bindTexture(c, &(u.texture->surface)); + } + } + } +} + +void ogles_unlock_textures(ogles_context_t* c) +{ + for (int i=0 ; irasterizer.state.texture[i].enable) { + texture_unit_t& u(c->textures.tmu[i]); + android_native_buffer_t* native_buffer = u.texture->buffer; + if (native_buffer) { + c->rasterizer.procs.activeTexture(c, i); + hw_module_t const* pModule; + if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule)) + continue; + + gralloc_module_t const* module = + reinterpret_cast(pModule); + buffer_handle_t bufferHandle; + native_buffer->getHandle(native_buffer, &bufferHandle); + module->unlock(module, bufferHandle); + u.texture->setImageBits(NULL); + c->rasterizer.procs.bindTexture(c, &(u.texture->surface)); + } + } + } + c->rasterizer.procs.activeTexture(c, c->textures.active); +} + // ---------------------------------------------------------------------------- #if 0 #pragma mark - @@ -592,6 +653,8 @@ invalid_enum: static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, ogles_context_t* c) { + ogles_lock_textures(c); + const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = gglIntToFixed(cbSurface.height) - (y + h); w >>= FIXED_BITS; @@ -650,6 +713,8 @@ static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h gglFixedToIntRound(y), gglFixedToIntRound(x)+w, gglFixedToIntRound(y)+h); + + ogles_unlock_textures(c); } static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, @@ -724,6 +789,8 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte goto slow_case; } + ogles_lock_textures(c); + c->rasterizer.procs.texCoord2i(c, s0, t0); const uint32_t enables = c->rasterizer.state.enables; if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG))) @@ -734,6 +801,9 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte c->rasterizer.procs.disable(c, GGL_AA); c->rasterizer.procs.shadeModel(c, GL_FLAT); c->rasterizer.procs.recti(c, x, y, x+w, y+h); + + ogles_unlock_textures(c); + return; } } @@ -1460,23 +1530,9 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) return; } - if (native_buffer->bits == NULL) { - // this buffer cannot be used with this implementation - ogles_error(c, GL_INVALID_VALUE); - return; - } - - GGLSurface sur; - sur.version = sizeof(GGLSurface); - sur.width = native_buffer->width; - sur.height= native_buffer->height; - sur.stride= native_buffer->stride; - sur.format= native_buffer->format; - sur.data = (GGLubyte*)native_buffer->bits; - // bind it to the texture unit sp tex = getAndBindActiveTextureObject(c); - tex->setSurface(&sur); + tex->setImage(native_buffer); /* * Here an implementation can retrieve the buffer_handle_t of this buffer diff --git a/opengl/libagl/texture.h b/opengl/libagl/texture.h index 5c57948c92d5..98f75509db22 100644 --- a/opengl/libagl/texture.h +++ b/opengl/libagl/texture.h @@ -32,13 +32,9 @@ namespace android { void ogles_init_texture(ogles_context_t* c); void ogles_uninit_texture(ogles_context_t* c); -void ogles_validate_texture_impl(ogles_context_t* c); - -inline void ogles_validate_texture(ogles_context_t* c) { - if (c->rasterizer.state.enables & GGL_ENABLE_TMUS) - ogles_validate_texture_impl(c); -} - +void ogles_validate_texture(ogles_context_t* c); +void ogles_lock_textures(ogles_context_t* c); +void ogles_unlock_textures(ogles_context_t* c); }; // namespace android diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk index d5ded42b5fb1..2876a1eec442 100644 --- a/opengl/tests/copybits/Android.mk +++ b/opengl/tests/copybits/Android.mk @@ -14,5 +14,5 @@ LOCAL_MODULE:= test-opengl-copybits LOCAL_MODULE_TAGS := tests -include $(BUILD_EXECUTABLE) +##include $(BUILD_EXECUTABLE) -- cgit v1.2.3-59-g8ed1b From ac2523b161df2bb507cc88906bb070878266770d Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 18:11:11 -0700 Subject: move opengl/include/EGL/android_natives.h to include/ui/egl/android_natives.h and don't include it from egl.h the android_native_ types are just forward declared in egl.h --- include/private/ui/SurfaceBuffer.h | 76 +++++++ include/ui/FramebufferNativeWindow.h | 23 +- include/ui/ISurface.h | 2 - include/ui/Surface.h | 40 +--- include/ui/egl/android_natives.h | 240 ++++++++++++++++++++ .../DisplayHardware/DisplayHardware.cpp | 1 - libs/surfaceflinger/LayerBitmap.h | 4 +- libs/ui/BufferMapper.cpp | 2 - libs/ui/FramebufferNativeWindow.cpp | 19 ++ libs/ui/ISurface.cpp | 1 + libs/ui/Surface.cpp | 5 +- opengl/include/EGL/android_natives.h | 241 --------------------- opengl/include/EGL/eglplatform.h | 4 +- opengl/libagl/TextureObjectManager.cpp | 2 + opengl/libagl/TextureObjectManager.h | 2 +- opengl/libagl/egl.cpp | 3 +- opengl/libagl/texture.cpp | 2 +- 17 files changed, 352 insertions(+), 315 deletions(-) create mode 100644 include/private/ui/SurfaceBuffer.h create mode 100644 include/ui/egl/android_natives.h delete mode 100644 opengl/include/EGL/android_natives.h (limited to 'opengl/libagl/TextureObjectManager.cpp') diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h new file mode 100644 index 000000000000..a6db50f4cf69 --- /dev/null +++ b/include/private/ui/SurfaceBuffer.h @@ -0,0 +1,76 @@ +/* + * 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 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(); + +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; +}; + +}; // namespace android + +#endif // ANDROID_UI_PRIVATE_SURFACE_BUFFER_H + diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 0db245af44dd..aad39a2a6b8b 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -21,13 +21,14 @@ #include #include -#include #include #include #include +#include + extern "C" EGLNativeWindowType android_createDisplaySurface(void); @@ -36,25 +37,7 @@ namespace android { // --------------------------------------------------------------------------- class Surface; - - -class NativeBuffer - : public EGLNativeBase< - android_native_buffer_t, - NativeBuffer, - LightRefBase > -{ -public: - NativeBuffer(int w, int h, int f, int u) : BASE() { - android_native_buffer_t::width = w; - android_native_buffer_t::height = h; - android_native_buffer_t::format = f; - android_native_buffer_t::usage = u; - } -private: - friend class LightRefBase; - ~NativeBuffer() { }; // this class cannot be overloaded -}; +class NativeBuffer; // --------------------------------------------------------------------------- diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h index 1a788720dbcd..e47b75362775 100644 --- a/include/ui/ISurface.h +++ b/include/ui/ISurface.h @@ -20,8 +20,6 @@ #include #include -#include - #include #include #include diff --git a/include/ui/Surface.h b/include/ui/Surface.h index e9bb1b3f473d..8c4f63ddfec0 100644 --- a/include/ui/Surface.h +++ b/include/ui/Surface.h @@ -28,7 +28,7 @@ #include #include -#include +#include namespace android { @@ -43,44 +43,6 @@ struct layer_cblk_t; // --------------------------------------------------------------------------- -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(); - -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; -}; - -// --------------------------------------------------------------------------- -class Surface; - class SurfaceControl : public RefBase { public: diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h new file mode 100644 index 000000000000..5842ee72ce7f --- /dev/null +++ b/include/ui/egl/android_natives.h @@ -0,0 +1,240 @@ +/* + * 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_H +#define ANDROID_ANDROID_NATIVES_H + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ + +#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \ + (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d)) + +#define ANDROID_NATIVE_WINDOW_MAGIC \ + ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d') + +#define ANDROID_NATIVE_BUFFER_MAGIC \ + ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r') + +// --------------------------------------------------------------------------- + +struct android_native_buffer_t; + +enum { + /* attributes of this surface or its updater */ + SURFACE_FLAG_PRESERVE_CONTENT = FRAMEBUFFER_RESERVED0, + SURFACE_FLAG_MAPPED = FRAMEBUFFER_FLAG_MAPPED, +}; + +// --------------------------------------------------------------------------- + +struct android_native_base_t +{ + /* a magic value defined by the actual EGL native type */ + int magic; + + /* the sizeof() of the actual EGL native type */ + int version; + + void* reserved[4]; + + /* reference-counting interface */ + void (*incRef)(struct android_native_base_t* base); + void (*decRef)(struct android_native_base_t* base); +}; + + +struct android_native_window_t +{ +#ifdef __cplusplus + android_native_window_t() + : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0) + { + common.magic = ANDROID_NATIVE_WINDOW_MAGIC; + common.version = sizeof(android_native_window_t); + memset(common.reserved, 0, sizeof(common.reserved)); + } +#endif + + struct android_native_base_t common; + + /* flags describing some attributes of this surface or its updater */ + const uint32_t flags; + + /* min swap interval supported by this updated */ + const int minSwapInterval; + + /* max swap interval supported by this updated */ + const int maxSwapInterval; + + /* horizontal and vertical resolution in DPI */ + const float xdpi; + const float ydpi; + + /* Some storage reserved for the OEM's driver. */ + intptr_t oem[4]; + + + /* + * Set the swap interval for this surface. + * + * Returns 0 on success or -errno on error. + */ + int (*setSwapInterval)(struct android_native_window_t* window, + int interval); + + /* + * hook called by EGL to acquire a buffer. After this call, the buffer + * is not locked, so its content cannot be modified. + * this call may block if no buffers are available. + * + * Returns 0 on success or -errno on error. + */ + int (*dequeueBuffer)(struct android_native_window_t* window, + struct android_native_buffer_t** buffer); + + /* + * hook called by EGL to lock a buffer. This MUST be called before modifying + * the content of a buffer. The buffer must have been acquired with + * dequeueBuffer first. + * + * Returns 0 on success or -errno on error. + */ + int (*lockBuffer)(struct android_native_window_t* window, + struct android_native_buffer_t* buffer); + /* + * hook called by EGL when modifications to the render buffer are done. + * This unlocks and post the buffer. + * + * Buffers MUST be queued in the same order than they were dequeued. + * + * Returns 0 on success or -errno on error. + */ + int (*queueBuffer)(struct android_native_window_t* window, + struct android_native_buffer_t* buffer); + + + void* reserved_proc[5]; +}; + + +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]; +}; + + +/* FIXME: this is legacy for pixmaps */ +struct egl_native_pixmap_t +{ + int32_t version; /* must be 32 */ + int32_t width; + int32_t height; + int32_t stride; + uint8_t* data; + uint8_t format; + uint8_t rfu[3]; + union { + uint32_t compressedFormat; + int32_t vstride; + }; + int32_t reserved; +}; + +/*****************************************************************************/ + +#ifdef __cplusplus +} +#endif + + +/*****************************************************************************/ + +#ifdef __cplusplus + +#include + +namespace android { + +/* + * This helper class turns an EGL android_native_xxx type into a C++ + * reference-counted object; with proper type conversions. + */ +template +class EGLNativeBase : public NATIVE_TYPE, public REF +{ +protected: + typedef EGLNativeBase BASE; + EGLNativeBase() : NATIVE_TYPE(), REF() { + NATIVE_TYPE::common.incRef = incRef; + NATIVE_TYPE::common.decRef = decRef; + } + static inline TYPE* getSelf(NATIVE_TYPE* self) { + return static_cast(self); + } + static inline TYPE const* getSelf(NATIVE_TYPE const* self) { + return static_cast(self); + } + static inline TYPE* getSelf(android_native_base_t* base) { + return getSelf(reinterpret_cast(base)); + } + static inline TYPE const * getSelf(android_native_base_t const* base) { + return getSelf(reinterpret_cast(base)); + } + static void incRef(android_native_base_t* base) { + EGLNativeBase* self = getSelf(base); + self->incStrong(self); + } + static void decRef(android_native_base_t* base) { + EGLNativeBase* self = getSelf(base); + self->decStrong(self); + } +}; + +} // namespace android +#endif // __cplusplus + +/*****************************************************************************/ + +#endif /* ANDROID_ANDROID_NATIVES_H */ diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index ca96e140ff7f..374f2e2c8b65 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index 6e136a2ae764..824e0f2b311b 100644 --- a/libs/surfaceflinger/LayerBitmap.h +++ b/libs/surfaceflinger/LayerBitmap.h @@ -28,12 +28,10 @@ #include #include -#include - #include #include - +#include class copybit_image_t; struct android_native_buffer_t; diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp index 1a75c5d9acdf..92a9a86bb0f2 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -25,8 +25,6 @@ #include #include -#include - #include diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index f235cb44a546..5e69cff985c7 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -42,6 +42,25 @@ namespace android { // ---------------------------------------------------------------------------- +class NativeBuffer + : public EGLNativeBase< + android_native_buffer_t, + NativeBuffer, + LightRefBase > +{ +public: + NativeBuffer(int w, int h, int f, int u) : BASE() { + android_native_buffer_t::width = w; + android_native_buffer_t::height = h; + android_native_buffer_t::format = f; + android_native_buffer_t::usage = u; + } +private: + friend class LightRefBase; + ~NativeBuffer() { }; // this class cannot be overloaded +}; + + /* * This implements the (main) framebuffer management. This class is used * mostly by SurfaceFlinger, but also by command line GL application. diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp index fcea8ec70121..ec922d0cf1b2 100644 --- a/libs/ui/ISurface.cpp +++ b/libs/ui/ISurface.cpp @@ -27,6 +27,7 @@ #include #include +#include namespace android { diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp index 782eac46beb8..6437619b20e2 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -36,12 +36,11 @@ #include #include -#include +#include #include #include - -#include +#include namespace android { diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h deleted file mode 100644 index b8465d580228..000000000000 --- a/opengl/include/EGL/android_natives.h +++ /dev/null @@ -1,241 +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. - */ - -#ifndef ANDROID_ANDROID_NATIVES_H -#define ANDROID_ANDROID_NATIVES_H - -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*****************************************************************************/ - -#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \ - (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d)) - -#define ANDROID_NATIVE_WINDOW_MAGIC \ - ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d') - -#define ANDROID_NATIVE_BUFFER_MAGIC \ - ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r') - -// --------------------------------------------------------------------------- - -struct android_native_buffer_t; - -enum { - /* attributes of this surface or its updater */ - SURFACE_FLAG_PRESERVE_CONTENT = FRAMEBUFFER_RESERVED0, - SURFACE_FLAG_MAPPED = FRAMEBUFFER_FLAG_MAPPED, -}; - - -// --------------------------------------------------------------------------- - -struct android_native_base_t -{ - /* a magic value defined by the actual EGL native type */ - int magic; - - /* the sizeof() of the actual EGL native type */ - int version; - - void* reserved[4]; - - /* reference-counting interface */ - void (*incRef)(struct android_native_base_t* base); - void (*decRef)(struct android_native_base_t* base); -}; - - -struct android_native_window_t -{ -#ifdef __cplusplus - android_native_window_t() - : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0) - { - common.magic = ANDROID_NATIVE_WINDOW_MAGIC; - common.version = sizeof(android_native_window_t); - memset(common.reserved, 0, sizeof(common.reserved)); - } -#endif - - struct android_native_base_t common; - - /* flags describing some attributes of this surface or its updater */ - const uint32_t flags; - - /* min swap interval supported by this updated */ - const int minSwapInterval; - - /* max swap interval supported by this updated */ - const int maxSwapInterval; - - /* horizontal and vertical resolution in DPI */ - const float xdpi; - const float ydpi; - - /* Some storage reserved for the OEM's driver. */ - intptr_t oem[4]; - - - /* - * Set the swap interval for this surface. - * - * Returns 0 on success or -errno on error. - */ - int (*setSwapInterval)(struct android_native_window_t* window, - int interval); - - /* - * hook called by EGL to acquire a buffer. After this call, the buffer - * is not locked, so its content cannot be modified. - * this call may block if no buffers are available. - * - * Returns 0 on success or -errno on error. - */ - int (*dequeueBuffer)(struct android_native_window_t* window, - struct android_native_buffer_t** buffer); - - /* - * hook called by EGL to lock a buffer. This MUST be called before modifying - * the content of a buffer. The buffer must have been acquired with - * dequeueBuffer first. - * - * Returns 0 on success or -errno on error. - */ - int (*lockBuffer)(struct android_native_window_t* window, - struct android_native_buffer_t* buffer); - /* - * hook called by EGL when modifications to the render buffer are done. - * This unlocks and post the buffer. - * - * Buffers MUST be queued in the same order than they were dequeued. - * - * Returns 0 on success or -errno on error. - */ - int (*queueBuffer)(struct android_native_window_t* window, - struct android_native_buffer_t* buffer); - - - void* reserved_proc[5]; -}; - - -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]; -}; - - -/* FIXME: this is legacy for pixmaps */ -struct egl_native_pixmap_t -{ - int32_t version; /* must be 32 */ - int32_t width; - int32_t height; - int32_t stride; - uint8_t* data; - uint8_t format; - uint8_t rfu[3]; - union { - uint32_t compressedFormat; - int32_t vstride; - }; - int32_t reserved; -}; - -/*****************************************************************************/ - -#ifdef __cplusplus -} -#endif - - -/*****************************************************************************/ - -#ifdef __cplusplus - -#include - -namespace android { - -/* - * This helper class turns an EGL android_native_xxx type into a C++ - * reference-counted object; with proper type conversions. - */ -template -class EGLNativeBase : public NATIVE_TYPE, public REF -{ -protected: - typedef EGLNativeBase BASE; - EGLNativeBase() : NATIVE_TYPE(), REF() { - NATIVE_TYPE::common.incRef = incRef; - NATIVE_TYPE::common.decRef = decRef; - } - static inline TYPE* getSelf(NATIVE_TYPE* self) { - return static_cast(self); - } - static inline TYPE const* getSelf(NATIVE_TYPE const* self) { - return static_cast(self); - } - static inline TYPE* getSelf(android_native_base_t* base) { - return getSelf(reinterpret_cast(base)); - } - static inline TYPE const * getSelf(android_native_base_t const* base) { - return getSelf(reinterpret_cast(base)); - } - static void incRef(android_native_base_t* base) { - EGLNativeBase* self = getSelf(base); - self->incStrong(self); - } - static void decRef(android_native_base_t* base) { - EGLNativeBase* self = getSelf(base); - self->decStrong(self); - } -}; - -} // namespace android -#endif // __cplusplus - -/*****************************************************************************/ - -#endif /* ANDROID_ANDROID_NATIVES_H */ diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h index d42808704dd6..956149091d81 100644 --- a/opengl/include/EGL/eglplatform.h +++ b/opengl/include/EGL/eglplatform.h @@ -89,7 +89,8 @@ typedef Window EGLNativeWindowType; #elif defined(ANDROID) -#include +struct android_native_window_t; +struct egl_native_pixmap_t; typedef struct android_native_window_t* EGLNativeWindowType; typedef struct egl_native_pixmap_t* EGLNativePixmapType; @@ -97,6 +98,7 @@ typedef void* EGLNativeDisplayType; #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 +struct android_native_buffer_t; #define EGL_NATIVE_BUFFER_ANDROID 0x6000 /* eglCreateImageKHR target */ #endif diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index 9eb99f0bc231..e5d4ed2b6f97 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -19,6 +19,8 @@ #include "context.h" #include "TextureObjectManager.h" +#include + namespace android { // ---------------------------------------------------------------------------- diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 29d50370eb41..e0eadf147959 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include "Tokenizer.h" #include "TokenManager.h" diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 720ba0bdaff3..0950f3ea2666 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -33,13 +33,14 @@ #include #include -#include #include #include #include #include +#include + #include "context.h" #include "state.h" #include "texture.h" diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 118964340f48..0211208e2f4a 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -23,7 +23,7 @@ #include "texture.h" #include "TextureObjectManager.h" -#include +#include #ifdef LIBAGL_USE_GRALLOC_COPYBITS #include "copybit.h" -- cgit v1.2.3-59-g8ed1b From b51e18d59b6f8e44a5d3516fc3359c54fa913331 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 May 2009 18:21:32 -0700 Subject: move android_native_buffer_t declaration into its own private/ui/android_native_priv.h header, since user code should never have access to it. --- include/private/ui/SurfaceBuffer.h | 2 +- include/private/ui/android_natives_priv.h | 62 +++++++++++++++++++++++++++++++ include/ui/egl/android_natives.h | 26 ------------- libs/ui/FramebufferNativeWindow.cpp | 2 + opengl/libagl/TextureObjectManager.cpp | 2 +- opengl/libagl/egl.cpp | 2 +- opengl/libagl/texture.cpp | 2 +- 7 files changed, 68 insertions(+), 30 deletions(-) create mode 100644 include/private/ui/android_natives_priv.h (limited to 'opengl/libagl/TextureObjectManager.cpp') diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h index a6db50f4cf69..c45abeb73c25 100644 --- a/include/private/ui/SurfaceBuffer.h +++ b/include/private/ui/SurfaceBuffer.h @@ -22,7 +22,7 @@ #include -#include +#include namespace android { diff --git a/include/private/ui/android_natives_priv.h b/include/private/ui/android_natives_priv.h new file mode 100644 index 000000000000..ee843e928100 --- /dev/null +++ b/include/private/ui/android_natives_priv.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 + +/*****************************************************************************/ + +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]; +}; + + +/*****************************************************************************/ + +#ifdef __cplusplus +} +#endif + +/*****************************************************************************/ + +#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */ diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index 5842ee72ce7f..fa3b7a0dc78d 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -139,32 +139,6 @@ struct android_native_window_t }; -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]; -}; - - /* FIXME: this is legacy for pixmaps */ struct egl_native_pixmap_t { diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 5e69cff985c7..4e692e2c27a1 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -38,6 +38,8 @@ #include #include +#include + // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index e5d4ed2b6f97..9deb2cf9eea4 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -19,7 +19,7 @@ #include "context.h" #include "TextureObjectManager.h" -#include +#include namespace android { // ---------------------------------------------------------------------------- diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 0950f3ea2666..1a774f59db22 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -39,7 +39,7 @@ #include #include -#include +#include #include "context.h" #include "state.h" diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 0211208e2f4a..d675107ca0b1 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -23,7 +23,7 @@ #include "texture.h" #include "TextureObjectManager.h" -#include +#include #ifdef LIBAGL_USE_GRALLOC_COPYBITS #include "copybit.h" -- cgit v1.2.3-59-g8ed1b From 350d651706d8f484d9aeb539d491526f822fa84a Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 10 Jun 2009 16:01:54 -0700 Subject: fix a bug where copybit only renders in the first buffer when used with s/w GL --- include/private/opengles/gl_context.h | 5 ++--- opengl/libagl/TextureObjectManager.cpp | 2 +- opengl/libagl/TextureObjectManager.h | 2 +- opengl/libagl/copybit.cpp | 27 +++++++++++++++++---------- opengl/libagl/copybit.h | 4 ++-- opengl/libagl/egl.cpp | 10 +++++----- opengl/libagl/state.cpp | 2 +- opengl/libagl/texture.cpp | 10 ++++------ opengl/tests/copybits/copybits.cpp | 16 +++++++--------- 9 files changed, 40 insertions(+), 38 deletions(-) (limited to 'opengl/libagl/TextureObjectManager.cpp') diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h index 641961f3a822..3b406779af5a 100644 --- a/include/private/opengles/gl_context.h +++ b/include/private/opengles/gl_context.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -600,9 +601,7 @@ struct copybits_context_t { copybit_device_t* blitEngine; int32_t minScale; int32_t maxScale; - // File descriptor of current drawing surface, if it's suitable for use as - // a copybits destination, else -1. - int drawSurfaceFd; + buffer_handle_t drawSurfaceBuffer; }; struct ogles_context_t { diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index 9deb2cf9eea4..255ccac3565b 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -56,7 +56,7 @@ void EGLTextureObject::init() generate_mipmap = GL_FALSE; direct = GL_FALSE; #ifdef LIBAGL_USE_GRALLOC_COPYBITS - copybits_fd = -1; + try_copybit = false; #endif // LIBAGL_USE_GRALLOC_COPYBITS buffer = 0; } diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index e0eadf147959..496e6947d737 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -80,7 +80,7 @@ public: GLint generate_mipmap; GLint direct; #ifdef LIBAGL_USE_GRALLOC_COPYBITS - int copybits_fd; + bool try_copybit; #endif // LIBAGL_USE_GRALLOC_COPYBITS android_native_buffer_t* buffer; }; diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 427e42aaf292..a539a2bdd5d7 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -27,23 +27,28 @@ #include "primitives.h" #include "texture.h" #include "BufferObjectManager.h" - #include "TextureObjectManager.h" + #include #include +#include #include "gralloc_priv.h" // ---------------------------------------------------------------------------- namespace android { -static void textureToCopyBitImage(const GGLSurface* surface, int fd, copybit_image_t* img) { +static void textureToCopyBitImage( + const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) +{ + // we know private_handle_t is good here + private_handle_t* hnd = (private_handle_t*)buffer; img->w = surface->stride; img->h = surface->height; img->format = surface->format; - img->offset = 0; + img->offset = hnd->offset; img->base = surface->data; - img->fd = fd; + img->fd = hnd->fd; } struct clipRectRegion : public copybit_region_t { @@ -109,7 +114,7 @@ static inline int fixedToByte(GGLfixed val) { static bool checkContext(ogles_context_t* c) { - // By convenction copybitQuickCheckContext() has already returned true. + // By convention copybitQuickCheckContext() has already returned true. // avoid checking the same information again. if (c->copybits.blitEngine == NULL @@ -118,7 +123,7 @@ static bool checkContext(ogles_context_t* c) { return false; } - // Note: The drawSurfaceFd is only set for destination + // Note: The drawSurfaceBuffer is only set for destination // surfaces types that are supported by the hardware and // do not have an alpha channel. So we don't have to re-check that here. @@ -237,18 +242,20 @@ static bool copybit(GLint x, GLint y, // LOGW("calling copybits"); copybit_device_t* copybit = c->copybits.blitEngine; + copybit_image_t dst; - textureToCopyBitImage(&cbSurface, c->copybits.drawSurfaceFd, &dst); + buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer; + textureToCopyBitImage(&cbSurface, target_hnd, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; + // we know private_handle_t is good here copybit_image_t src; - textureToCopyBitImage(&textureObject->surface, textureObject->copybits_fd, - &src); + buffer_handle_t source_hnd = textureObject->buffer->handle; + textureToCopyBitImage(&textureObject->surface, source_hnd, &src); copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h index 1888aee1929e..401b68c2914a 100644 --- a/opengl/libagl/copybit.h +++ b/opengl/libagl/copybit.h @@ -32,9 +32,9 @@ bool drawTrangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count); inline bool copybitQuickCheckContext(ogles_context_t* c) { - return c->copybits.drawSurfaceFd >= 0 + return c->copybits.drawSurfaceBuffer != 0 && c->rasterizer.state.enabled_tmu == 1 - && c->textures.tmu[0].texture->copybits_fd >= 0; + && c->textures.tmu[0].texture->try_copybit; } /* diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 0df2bbaa584f..c6d50578869a 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -551,20 +551,20 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) gl->rasterizer.procs.colorBuffer(gl, &buffer); if (depth.data != gl->rasterizer.state.buffers.depth.data) gl->rasterizer.procs.depthBuffer(gl, &depth); + #ifdef LIBAGL_USE_GRALLOC_COPYBITS - gl->copybits.drawSurfaceFd = -1; + gl->copybits.drawSurfaceBuffer = 0; if (supportedCopybitsDestinationFormat(buffer.format)) { buffer_handle_t handle = this->buffer->handle; if (handle != NULL) { private_handle_t* hand = private_handle_t::dynamicCast(handle); - if (hand != NULL) { - if (hand->usesPhysicallyContiguousMemory()) { - gl->copybits.drawSurfaceFd = hand->fd; - } + if (hand != NULL && hand->usesPhysicallyContiguousMemory()) { + gl->copybits.drawSurfaceBuffer = handle; } } } #endif // LIBAGL_USE_GRALLOC_COPYBITS + return EGL_TRUE; } EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl) diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp index a00f779d6d35..a59b3b046e3f 100644 --- a/opengl/libagl/state.cpp +++ b/opengl/libagl/state.cpp @@ -101,7 +101,7 @@ ogles_context_t *ogles_init(size_t extra) c->copybits.blitEngine = NULL; c->copybits.minScale = 0; c->copybits.maxScale = 0; - c->copybits.drawSurfaceFd = -1; + c->copybits.drawSurfaceBuffer = 0; #ifdef LIBAGL_USE_GRALLOC_COPYBITS hw_module_t const* module; diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index d675107ca0b1..05fd46e5a2b0 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1544,12 +1544,10 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) * */ #ifdef LIBAGL_USE_GRALLOC_COPYBITS - tex->copybits_fd = -1; - private_handle_t* hand; - if ((hand = private_handle_t::dynamicCast(native_buffer->handle)) != NULL) { - if (hand->usesPhysicallyContiguousMemory()) { - tex->copybits_fd = hand->fd; - } + tex->try_copybit = false; + private_handle_t* hnd = private_handle_t::dynamicCast(native_buffer->handle); + if (hnd && hnd->usesPhysicallyContiguousMemory()) { + tex->try_copybit = true; } #endif // LIBAGL_USE_GRALLOC_COPYBITS } diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp index d15526c65e94..f8ca9b2e0eee 100644 --- a/opengl/tests/copybits/copybits.cpp +++ b/opengl/tests/copybits/copybits.cpp @@ -96,13 +96,11 @@ private: status_t initSize(uint32_t w, uint32_t h); ssize_t mInitCheck; - uint32_t mFlags; - uint32_t mVStride; void* mData; }; Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage) - : SurfaceBuffer(), mInitCheck(NO_INIT), mVStride(0) + : SurfaceBuffer(), mInitCheck(NO_INIT) { this->usage = usage; this->format = format; @@ -137,7 +135,6 @@ status_t Buffer::initSize(uint32_t w, uint32_t h) if (err == NO_ERROR) { width = w; height = h; - mVStride = 0; } } @@ -154,7 +151,6 @@ status_t Buffer::lock(GGLSurface* sur, uint32_t usage) sur->height = height; sur->stride = stride; sur->format = format; - sur->vstride = mVStride; sur->data = static_cast(vaddr); } return res; @@ -355,7 +351,7 @@ void init_scene(void) // #define USE_ALPHA_COLOR #define USE_GL_REPLACE -// #define USE_GL_MODULATE +//#define USE_GL_MODULATE // #define USE_BLEND @@ -479,7 +475,7 @@ static const int SCALE_COUNT = 12; int scale(int base, int factor) { static const float kTable[SCALE_COUNT] = { - 0.1f, 0.25f, 0.5f, 0.75f, 1.0f, + 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]; @@ -570,10 +566,10 @@ int testStretch() return -1; } // Need to do a dummy eglSwapBuffers first. Don't know why. - glClearColor(0.4, 1.0, 0.4, 0.4); + 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); @@ -592,6 +588,8 @@ int testStretch() } eglSwapBuffers(eglDisplay, eglSurface); + LOGD("wait 1s"); + usleep(1000000); } return 0; } -- cgit v1.2.3-59-g8ed1b