removed the "bits" attribute from android_native_buffer_t.
"bits" can never be trusted now that we need to call lock() on the handle to get the virtual address of the buffer.
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 6eb06ae..ce50719 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -54,8 +54,8 @@
return handle;
}
- status_t lock(uint32_t usage);
- status_t lock(uint32_t usage, const Rect& rect);
+ status_t lock(uint32_t usage, void** vaddr);
+ status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
status_t unlock();
protected:
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index 38d4bcf..765d90b 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -116,7 +116,8 @@
status_t Buffer::lock(GGLSurface* sur, uint32_t usage)
{
- status_t res = SurfaceBuffer::lock(usage);
+ void* vaddr;
+ status_t res = SurfaceBuffer::lock(usage, &vaddr);
if (res == NO_ERROR && sur) {
sur->version = sizeof(GGLSurface);
sur->width = width;
@@ -124,7 +125,7 @@
sur->stride = stride;
sur->format = format;
sur->vstride = mVStride;
- sur->data = static_cast<GGLubyte*>(bits);
+ sur->data = static_cast<GGLubyte*>(vaddr);
}
return res;
}
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 68fd963..5f2138e 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -90,23 +90,22 @@
return 0;
}
-status_t SurfaceBuffer::lock(uint32_t usage)
+status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr)
{
const Rect lockBounds(width, height);
- status_t res = lock(usage, lockBounds);
+ status_t res = lock(usage, lockBounds, vaddr);
return res;
}
-status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect)
+status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
{
- status_t res = getBufferMapper().lock(handle, usage, rect, &bits);
+ status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
return res;
}
status_t SurfaceBuffer::unlock()
{
status_t res = getBufferMapper().unlock(handle);
- bits = NULL;
return res;
}
@@ -134,11 +133,11 @@
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;
+ uint8_t const * src_bits;
+ src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
- dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds());
- uint8_t* const dst_bits = (uint8_t*)dst->bits;
+ uint8_t* dst_bits;
+ dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
Region::iterator iterator(reg);
if (iterator) {
@@ -629,9 +628,10 @@
mDirtyRegion = newDirtyRegion;
mOldDirtyRegion = newDirtyRegion;
+ void* vaddr;
status_t res = backBuffer->lock(
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
- newDirtyRegion.bounds());
+ newDirtyRegion.bounds(), &vaddr);
LOGW_IF(res, "failed locking buffer %d (%p)",
mBackbufferIndex, backBuffer->handle);
@@ -642,7 +642,7 @@
other->s = backBuffer->stride;
other->usage = backBuffer->usage;
other->format = backBuffer->format;
- other->bits = backBuffer->bits;
+ other->bits = vaddr;
}
}
return err;
@@ -660,7 +660,6 @@
mBackbufferIndex, mLockedBuffer->handle);
status_t err = queueBuffer(mLockedBuffer);
- mLockedBuffer->bits = NULL;
mLockedBuffer = 0;
return err;
}
diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h
index 329705b..8db2bb3 100644
--- a/opengl/include/EGL/android_natives.h
+++ b/opengl/include/EGL/android_natives.h
@@ -157,9 +157,8 @@
int stride;
int format;
int usage;
- void* bits; // non-zero if buffer is locked for sw usage
- void* reserved[2];
+ void* reserved[3];
int (*getHandle)(struct android_native_buffer_t const * base,
buffer_handle_t* handle);
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 04ca431..67dfd3e 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -146,9 +146,10 @@
virtual EGLBoolean bindDrawSurface(ogles_context_t* gl) = 0;
virtual EGLBoolean bindReadSurface(ogles_context_t* gl) = 0;
+ virtual void connect() {}
+ virtual void disconnect() {}
virtual EGLint getWidth() const = 0;
virtual EGLint getHeight() const = 0;
- virtual void* getBits() const = 0;
virtual EGLint getHorizontalResolution() const;
virtual EGLint getVerticalResolution() const;
@@ -204,21 +205,24 @@
virtual EGLBoolean swapBuffers();
virtual EGLBoolean bindDrawSurface(ogles_context_t* gl);
virtual EGLBoolean bindReadSurface(ogles_context_t* gl);
+ virtual void connect();
+ virtual void disconnect();
virtual EGLint getWidth() const { return buffer->width; }
virtual EGLint getHeight() const { return buffer->height; }
- virtual void* getBits() const;
virtual EGLint getHorizontalResolution() const;
virtual EGLint getVerticalResolution() const;
virtual EGLint getRefreshRate() const;
virtual EGLint getSwapBehavior() const;
+
private:
- status_t lock(android_native_buffer_t* buf, int usage);
+ status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
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;
+ void* bits;
};
egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
@@ -226,7 +230,7 @@
int32_t depthFormat,
android_native_window_t* window)
: egl_surface_t(dpy, config, depthFormat),
- nativeWindow(window), buffer(0), module(0)
+ nativeWindow(window), buffer(0), module(0), bits(NULL)
{
hw_module_t const* pModule;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
@@ -249,20 +253,26 @@
}
}
- // TODO: lockBuffer should rather be executed when the very first
- // direct rendering occurs.
buffer->common.incRef(&buffer->common);
- nativeWindow->lockBuffer(nativeWindow, buffer);
+}
+void egl_window_surface_v2_t::connect()
+{
// 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.
+ nativeWindow->lockBuffer(nativeWindow, buffer);
+ lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits);
+}
+
+void egl_window_surface_v2_t::disconnect()
+{
+ if (buffer) {
+ bits = NULL;
+ unlock(buffer);
+ }
}
status_t egl_window_surface_v2_t::lock(
- android_native_buffer_t* buf, int usage)
+ android_native_buffer_t* buf, int usage, void** vaddr)
{
int err;
buffer_handle_t bufferHandle;
@@ -271,7 +281,7 @@
return err;
err = module->lock(module, bufferHandle,
- usage, 0, 0, buf->width, buf->height, &buf->bits);
+ usage, 0, 0, buf->width, buf->height, vaddr);
return err;
}
@@ -284,14 +294,12 @@
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);
@@ -317,9 +325,9 @@
// TODO: lockBuffer should rather be executed when the very first
// direct rendering occurs.
+ void* vaddr;
nativeWindow->lockBuffer(nativeWindow, buffer);
- lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
-
+ lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits);
if ((width != buffer->width) || (height != buffer->height)) {
// TODO: we probably should reset the swap rect here
@@ -363,7 +371,7 @@
buffer.width = this->buffer->width;
buffer.height = this->buffer->height;
buffer.stride = this->buffer->stride;
- buffer.data = (GGLubyte*)this->buffer->bits;
+ buffer.data = (GGLubyte*)bits;
buffer.format = this->buffer->format;
gl->rasterizer.procs.colorBuffer(gl, &buffer);
if (depth.data != gl->rasterizer.state.buffers.depth.data)
@@ -392,14 +400,11 @@
buffer.width = this->buffer->width;
buffer.height = this->buffer->height;
buffer.stride = this->buffer->stride;
- buffer.data = (GGLubyte*)this->buffer->bits;
+ buffer.data = (GGLubyte*)bits; // FIXME: hopefully is is LOCKED!!!
buffer.format = this->buffer->format;
gl->rasterizer.procs.readBuffer(gl, &buffer);
return EGL_TRUE;
}
-void* egl_window_surface_v2_t::getBits() const {
- return (GGLubyte*)buffer->bits;
-}
EGLint egl_window_surface_v2_t::getHorizontalResolution() const {
return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
}
@@ -434,7 +439,6 @@
virtual EGLBoolean bindReadSurface(ogles_context_t* gl);
virtual EGLint getWidth() const { return nativePixmap.width; }
virtual EGLint getHeight() const { return nativePixmap.height; }
- virtual void* getBits() const { return nativePixmap.data; }
private:
egl_native_pixmap_t nativePixmap;
};
@@ -499,7 +503,6 @@
virtual EGLBoolean bindReadSurface(ogles_context_t* gl);
virtual EGLint getWidth() const { return pbuffer.width; }
virtual EGLint getHeight() const { return pbuffer.height; }
- virtual void* getBits() const { return pbuffer.data; }
private:
GGLSurface pbuffer;
};
@@ -1311,6 +1314,11 @@
return setError(EGL_BAD_SURFACE, EGL_FALSE);
if (surface->dpy != dpy)
return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+ if (surface->ctx) {
+ // FIXME: this surface is current check what the spec says
+ surface->disconnect();
+ surface->ctx = 0;
+ }
delete surface;
}
return EGL_TRUE;
@@ -1436,21 +1444,28 @@
egl_surface_t* r = (egl_surface_t*)read;
if ((d && d->ctx && d->ctx != ctx) ||
(r && r->ctx && r->ctx != ctx)) {
- // once of the surface is bound to a context in another thread
+ // one of the surface is bound to a context in another thread
return setError(EGL_BAD_ACCESS, EGL_FALSE);
}
}
- // TODO: call connect / disconnect on the surface
-
ogles_context_t* gl = (ogles_context_t*)ctx;
if (makeCurrent(gl) == 0) {
if (ctx) {
egl_context_t* c = egl_context_t::context(ctx);
egl_surface_t* d = (egl_surface_t*)draw;
egl_surface_t* r = (egl_surface_t*)read;
- c->read = read;
+
+ if (c->draw) {
+ reinterpret_cast<egl_surface_t*>(c->draw)->disconnect();
+ }
+ if (c->read) {
+ // FIXME: unlock/disconnect the read surface too
+ }
+
c->draw = draw;
+ c->read = read;
+
if (c->flags & egl_context_t::NEVER_CURRENT) {
c->flags &= ~egl_context_t::NEVER_CURRENT;
GLint w = 0;
@@ -1464,10 +1479,12 @@
ogles_scissor(gl, 0, 0, w, h);
}
if (d) {
+ d->connect();
d->ctx = ctx;
d->bindDrawSurface(gl);
}
if (r) {
+ // FIXME: lock/connect the read surface too
r->ctx = ctx;
r->bindReadSurface(gl);
}
@@ -1478,8 +1495,14 @@
egl_context_t* c = egl_context_t::context(current_ctx);
egl_surface_t* d = (egl_surface_t*)c->draw;
egl_surface_t* r = (egl_surface_t*)c->read;
- if (d) d->ctx = EGL_NO_CONTEXT;
- if (r) r->ctx = EGL_NO_CONTEXT;
+ if (d) {
+ d->ctx = EGL_NO_CONTEXT;
+ d->disconnect();
+ }
+ if (r) {
+ r->ctx = EGL_NO_CONTEXT;
+ // FIXME: unlock/disconnect the read surface too
+ }
}
}
return EGL_TRUE;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index f2d8da3..9bcbfdd 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -141,12 +141,13 @@
reinterpret_cast<gralloc_module_t const*>(pModule);
buffer_handle_t bufferHandle;
native_buffer->getHandle(native_buffer, &bufferHandle);
+ void* vaddr;
int err = module->lock(module, bufferHandle,
GRALLOC_USAGE_SW_READ_OFTEN,
0, 0, native_buffer->width, native_buffer->height,
- &native_buffer->bits);
+ &vaddr);
- u.texture->setImageBits(native_buffer->bits);
+ u.texture->setImageBits(vaddr);
c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
}
}