diff options
author | Mathias Agopian <mathias@google.com> | 2009-05-04 14:17:04 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-05-04 14:17:04 -0700 |
commit | dff8e58d47ede6e748c0b02e128ca33b42a4f362 (patch) | |
tree | 716d70cda74aa625d6e67c4debc2eb7c6b81bfc9 | |
parent | fa6eda01a9f3df0102ce6a65302c8674cc9c7e50 (diff) | |
download | frameworks_base-dff8e58d47ede6e748c0b02e128ca33b42a4f362.zip frameworks_base-dff8e58d47ede6e748c0b02e128ca33b42a4f362.tar.gz frameworks_base-dff8e58d47ede6e748c0b02e128ca33b42a4f362.tar.bz2 |
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
38 files changed, 431 insertions, 649 deletions
diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h index ff90033..5f084be 100644 --- a/include/ui/BufferMapper.h +++ b/include/ui/BufferMapper.h @@ -20,10 +20,7 @@ #include <stdint.h> #include <sys/types.h> -#include <utils/CallStack.h> -#include <utils/threads.h> #include <utils/Singleton.h> -#include <utils/KeyedVector.h> #include <hardware/gralloc.h> @@ -40,9 +37,14 @@ class BufferMapper : public Singleton<BufferMapper> { 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>; 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<buffer_handle_t, Vector<map_info_t> > mMapInfo; }; // --------------------------------------------------------------------------- diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h deleted file mode 100644 index a8b5853..0000000 --- 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 <stdint.h> -#include <sys/types.h> - -#include <utils/Timers.h> - -#include <ui/EGLNativeSurface.h> - -#include <pixelflinger/pixelflinger.h> -#include <linux/fb.h> - -#include <EGL/egl.h> - -struct copybit_device_t; -struct copybit_image_t; - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Region; -class Rect; - -class EGLDisplaySurface : public EGLNativeSurface<EGLDisplaySurface> -{ -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/FramebufferNativeWindow.h index 4b25655..1d49cca 100644 --- a/include/ui/EGLNativeWindowSurface.h +++ b/include/ui/FramebufferNativeWindow.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef ANDROID_EGL_NATIVE_WINDOW_SURFACE_H -#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H +#ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H +#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H #include <stdint.h> #include <sys/types.h> @@ -76,32 +76,18 @@ public: framebuffer_device_t const * getDevice() const { return fbDev; } + void setSwapRectangle(const Rect& dirty); + private: friend class LightRefBase<FramebufferNativeWindow>; ~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<FramebufferNativeWindow*>(window); - return self; - } - - static inline FramebufferNativeWindow* getSelf( - android_native_base_t* window) { - return getSelf(reinterpret_cast<android_native_window_t*>(window)); - } - - framebuffer_device_t* fbDev; alloc_device_t* grDev; @@ -121,5 +107,5 @@ private: }; // namespace android // --------------------------------------------------------------------------- -#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H +#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H diff --git a/include/ui/Region.h b/include/ui/Region.h index 7689673..5efeff7 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 16d2edb..6eb06ae 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<SurfaceBuffer>; @@ -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<ISurface>& 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<SurfaceBuffer>* buffer); + status_t lockBuffer(const sp<SurfaceBuffer>& buffer); + status_t queueBuffer(const sp<SurfaceBuffer>& buffer); + alloc_device_t* mAllocDevice; sp<SurfaceComposerClient> mClient; sp<ISurface> mSurface; sp<SurfaceBuffer> mBuffers[2]; - android_native_buffer_t* mLockedBuffer; + sp<SurfaceBuffer> 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 cbda0fd..bd7f28c 100644 --- a/include/utils/RefBase.h +++ b/include/utils/RefBase.h @@ -156,6 +156,10 @@ public: delete static_cast<const T*>(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 2b360d6..639a82e 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 ee36b67..b45fe34 100644 --- a/libs/surfaceflinger/BootAnimation.cpp +++ b/libs/surfaceflinger/BootAnimation.cpp @@ -32,7 +32,7 @@ #include <ui/DisplayInfo.h> #include <ui/ISurfaceComposer.h> #include <ui/ISurfaceFlingerClient.h> -#include <ui/EGLNativeWindowSurface.h> +#include <ui/FramebufferNativeWindow.h> #include <core/SkBitmap.h> #include <images/SkImageDecoder.h> diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp index fec7c87..cee8b64 100644 --- a/libs/surfaceflinger/BufferAllocator.cpp +++ b/libs/surfaceflinger/BufferAllocator.cpp @@ -16,20 +16,14 @@ */ #include <sys/mman.h> -#include <utils/CallStack.h> #include <cutils/ashmem.h> #include <cutils/log.h> #include <utils/Singleton.h> #include <utils/String8.h> -#include <ui/BufferMapper.h> - #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 ; i<c ; i++) { const alloc_rec_t& rec(list.valueAt(i)); - snprintf(buffer, SIZE, "%10p: %10p | %7.2f KB | %4u x %4u | %2d | 0x%08x\n", - list.keyAt(i), rec.vaddr, rec.size/1024.0f, + snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u x %4u | %2d | 0x%08x\n", + list.keyAt(i), rec.size/1024.0f, rec.w, rec.h, rec.format, rec.usage); result.append(buffer); total += rec.size; @@ -108,23 +102,9 @@ status_t BufferAllocator::free(buffer_handle_t handle) { Mutex::Autolock _l(mLock); -#if ANDROID_GRALLOC_DEBUG - void* base = (void*)(handle->data[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<buffer_handle_t, alloc_rec_t>& 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<buffer_handle_t, alloc_rec_t>& 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<buffer_handle_t, alloc_rec_t>& 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 0b69b8e..a279ded 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 1f7211c..83ebd7a 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -25,7 +25,7 @@ #include <utils/Log.h> #include <ui/PixelFormat.h> -#include <ui/EGLNativeWindowSurface.h> +#include <ui/FramebufferNativeWindow.h> #include <GLES/gl.h> #include <EGL/egl.h> @@ -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 8a7d467..7625931 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -69,8 +69,6 @@ void Layer::destroy() { for (int i=0 ; i<NUM_BUFFERS ; i++) { if (mTextures[i].name != -1U) { - // FIXME: this was originally to work-around a bug in the - // adreno driver. this should be fixed now. glDeleteTextures(1, &mTextures[i].name); mTextures[i].name = -1U; } @@ -142,8 +140,8 @@ status_t Layer::setBuffers( Client* client, void Layer::reloadTexture(const Region& dirty) { - const sp<const Buffer>& buffer(frontBuffer().getBuffer()); - if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) { + const sp<Buffer>& 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<const Buffer> buffer(frontBuffer().getBuffer()); - buffer->getBitmapSurface(&t); - drawWithOpenGL(clip, textureName, t); + drawWithOpenGL(clip, textureName, buffer); } sp<SurfaceBuffer> Layer::peekBuffer() diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index ef5a959..cc9c586 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<const Buffer>& 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 c177c2a..509dedd 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<const Buffer>& buffer, int transform = 0) const; void clearWithOpenGL(const Region& clip) const; diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp index d633a2d..38d4bcf 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<GGLubyte*>(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<GGLubyte*>(bits); - return NO_ERROR; -} + // =========================================================================== // LayerBitmap diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h index e673755..6e136a2 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 9339b87..8be91c9 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> buffer(getBuffer()); + // FIXME: we should get a native buffer here + /* + sp<Buffer> 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/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 6b42158..5fd979e 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 319f80e..d5e5252 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/LayerOrientationAnim.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp index 41c42d1..41c42d1 100644 --- a/libs/surfaceflinger/LayerOrientationAnim.cpp +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h index 472c45a..472c45a 100644 --- a/libs/surfaceflinger/LayerOrientationAnim.h +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp index dc6b632..dc6b632 100644 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h index a675c79..a675c79 100644 --- a/libs/surfaceflinger/LayerOrientationAnimRotate.h +++ b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp index a6c9c28..a6c9c28 100644 --- a/libs/surfaceflinger/OrientationAnimation.cpp +++ b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h index 8ba6621..8ba6621 100644 --- a/libs/surfaceflinger/OrientationAnimation.h +++ b/libs/surfaceflinger/purgatory/OrientationAnimation.h diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 577dd4b..d44d2f9 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 85a029b..1a75c5d 100644 --- a/libs/ui/BufferMapper.cpp +++ b/libs/ui/BufferMapper.cpp @@ -17,14 +17,9 @@ #define LOG_TAG "BufferMapper" #include <stdint.h> -#include <unistd.h> -#include <fcntl.h> #include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> #include <utils/Errors.h> -#include <utils/threads.h> #include <utils/Log.h> #include <ui/BufferMapper.h> @@ -34,12 +29,6 @@ #include <hardware/gralloc.h> -// --------------------------------------------------------------------------- -// 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<map_info_t>& infos = mMapInfo.editValueAt(index); - infos.add(info); - } else { - Vector<map_info_t> 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<map_info_t>& infos = mMapInfo.editValueAt(index); - ssize_t count = infos.size(); - for (int i=0 ; i<count ; ) { - if (infos[i].id == id) { - infos.removeAt(i); - --count; - } else { - ++i; - } - } - if (count == 0) { - mMapInfo.removeItemsAt(index, 1); - } -} - -void BufferMapper::dump(buffer_handle_t handle) -{ - Mutex::Autolock _l(mLock); - ssize_t index = mMapInfo.indexOfKey(handle); - if (index < 0) { - LOGD("handle %p is not mapped through BufferMapper", handle); - return; - } - - const Vector<map_info_t>& infos = mMapInfo.valueAt(index); - ssize_t count = infos.size(); - for (int i=0 ; i<count ; i++) { - LOGD("#%d", i); - infos[i].stack.dump(); - } -} - // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/FramebufferNativeWindow.cpp index 5d9d6a4..407d6f4 100644 --- a/libs/ui/EGLNativeWindowSurface.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -15,7 +15,7 @@ ** limitations under the License. */ -#define LOG_TAG "EGLNativeWindowSurface" +#define LOG_TAG "FramebufferNativeWindow" #include <stdlib.h> #include <stdio.h> @@ -28,7 +28,7 @@ #include <ui/SurfaceComposerClient.h> #include <ui/Rect.h> -#include <ui/EGLNativeWindowSurface.h> +#include <ui/FramebufferNativeWindow.h> #include <EGL/egl.h> @@ -87,13 +87,6 @@ FramebufferNativeWindow::FramebufferNativeWindow() 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<gralloc_module_t*>(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; @@ -125,10 +118,7 @@ FramebufferNativeWindow::FramebufferNativeWindow() const_cast<int&>(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; @@ -137,10 +127,6 @@ FramebufferNativeWindow::FramebufferNativeWindow() FramebufferNativeWindow::~FramebufferNativeWindow() { grDev->free(grDev, buffers[0]->handle); grDev->free(grDev, buffers[1]->handle); - gralloc_module_t* m = - reinterpret_cast<gralloc_module_t*>(grDev->common.module); - m->unmap(m, buffers[0]->handle); - m->unmap(m, buffers[1]->handle); gralloc_close(grDev); framebuffer_close(fbDev); } @@ -160,13 +146,10 @@ int FramebufferNativeWindow::setSwapInterval( return fb->setSwapInterval(fb, interval); } -int FramebufferNativeWindow::setSwapRectangle(android_native_window_t* window, - int l, int t, int w, int h) +void FramebufferNativeWindow::setSwapRectangle(const Rect& dirty) { - FramebufferNativeWindow* self = getSelf(window); - Mutex::Autolock _l(self->mutex); - self->mDirty = Rect(l, t, l+w, t+h); - return 0; + Mutex::Autolock _l(mutex); + mDirty = dirty; } int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, @@ -201,16 +184,8 @@ int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, while (self->front == buffer) { self->mCondition.wait(self->mutex); } - - gralloc_module_t* m = - reinterpret_cast<gralloc_module_t*>(self->grDev->common.module); - const Rect& dirty(self->mDirty); - buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle; - int res = m->lock(m, handle, GRALLOC_USAGE_HW_FB, - dirty.left, dirty.right, dirty.width(), dirty.height()); - - return res; + return NO_ERROR; } int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, @@ -219,13 +194,8 @@ int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, FramebufferNativeWindow* self = getSelf(window); Mutex::Autolock _l(self->mutex); framebuffer_device_t* fb = self->fbDev; - gralloc_module_t* m = - reinterpret_cast<gralloc_module_t*>(self->grDev->common.module); - buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle; - m->unlock(m, handle); int res = fb->post(fb, handle); - self->front = static_cast<NativeBuffer*>(buffer); self->mNumFreeBuffers++; self->mCondition.broadcast(); diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 26e694a..30da911 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 fb105b3..68fd963 100644 --- a/libs/ui/Surface.cpp +++ b/libs/ui/Surface.cpp @@ -31,7 +31,6 @@ #include <ui/DisplayInfo.h> #include <ui/BufferMapper.h> -#include <ui/EGLNativeWindowSurface.h> #include <ui/ISurface.h> #include <ui/Surface.h> #include <ui/SurfaceComposerClient.h> @@ -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<SurfaceBuffer>& dst, + const sp<SurfaceBuffer>& 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<Surface> SurfaceControl::getSurface() const Surface::Surface(const sp<SurfaceControl>& 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<IBinder> clientBinder = parcel.readStrongBinder(); mSurface = interface_cast<ISurface>(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<float&>(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<SurfaceBuffer>* buffer) +{ + android_native_buffer_t* out; + status_t err = dequeueBuffer(&out); + *buffer = SurfaceBuffer::getSelf(out); + return err; +} + +status_t Surface::lockBuffer(const sp<SurfaceBuffer>& buffer) +{ + return lockBuffer(buffer.get()); +} + +status_t Surface::queueBuffer(const sp<SurfaceBuffer>& 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<SurfaceBuffer>& 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<SurfaceBuffer> 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<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]); - if (!copyback.isEmpty() && frontBuffer!=0) { - // copy front to back - copyBlt(backBuffer, frontBuffer.get(), copyback); + const sp<SurfaceBuffer>& 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<SurfaceBuffer>& 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 e3c3b86..329705b 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 f927de9..9eb99f0 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<EGLTextureObject>& 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 497528c..29d5037 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -30,6 +30,7 @@ #include <private/pixelflinger/ggl_context.h> #include <GLES/gl.h> +#include <EGL/android_natives.h> #include "Tokenizer.h" #include "TokenManager.h" @@ -39,22 +40,20 @@ namespace android { // ---------------------------------------------------------------------------- -class EGLTextureObject +class EGLTextureObject : public LightRefBase<EGLTextureObject> { 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<EGLSurfaceManager>, + 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<EGLTextureObject> createTexture(GLuint name); sp<EGLTextureObject> removeTexture(GLuint name); sp<EGLTextureObject> replaceTexture(GLuint name); @@ -121,21 +102,10 @@ public: sp<EGLTextureObject> texture(GLuint name); private: - mutable int32_t mCount; mutable Mutex mLock; KeyedVector< GLuint, sp<EGLTextureObject> > 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 eefe614..6d2cc91 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 9384e18..04ca431 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<gralloc_module_t const*>(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<gralloc_module_t const*>(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<gralloc_module_t const*>(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 9dca133..f2d8da3 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 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) { if (c->rasterizer.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 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) { + if (c->rasterizer.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<gralloc_module_t const*>(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 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) { + if (c->rasterizer.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<gralloc_module_t const*>(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<EGLTextureObject> 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 5c57948..98f7550 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 d5ded42..2876a1e 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) |