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 /opengl | |
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
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/include/EGL/android_natives.h | 26 | ||||
-rw-r--r-- | opengl/libagl/TextureObjectManager.cpp | 20 | ||||
-rw-r--r-- | opengl/libagl/TextureObjectManager.h | 50 | ||||
-rw-r--r-- | opengl/libagl/array.cpp | 17 | ||||
-rw-r--r-- | opengl/libagl/egl.cpp | 71 | ||||
-rw-r--r-- | opengl/libagl/texture.cpp | 88 | ||||
-rw-r--r-- | opengl/libagl/texture.h | 10 | ||||
-rw-r--r-- | opengl/tests/copybits/Android.mk | 2 |
8 files changed, 166 insertions, 118 deletions
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) |