summaryrefslogtreecommitdiffstats
path: root/opengl
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-05-04 14:17:04 -0700
committerMathias Agopian <mathias@google.com>2009-05-04 14:17:04 -0700
commitdff8e58d47ede6e748c0b02e128ca33b42a4f362 (patch)
tree716d70cda74aa625d6e67c4debc2eb7c6b81bfc9 /opengl
parentfa6eda01a9f3df0102ce6a65302c8674cc9c7e50 (diff)
downloadframeworks_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.h26
-rw-r--r--opengl/libagl/TextureObjectManager.cpp20
-rw-r--r--opengl/libagl/TextureObjectManager.h50
-rw-r--r--opengl/libagl/array.cpp17
-rw-r--r--opengl/libagl/egl.cpp71
-rw-r--r--opengl/libagl/texture.cpp88
-rw-r--r--opengl/libagl/texture.h10
-rw-r--r--opengl/tests/copybits/Android.mk2
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)