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.
This commit is contained in:
Mathias Agopian
2009-05-05 00:37:46 -07:00
parent 6279619e42
commit 430f2ed5c0
6 changed files with 73 additions and 50 deletions

View File

@@ -54,8 +54,8 @@ public:
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:

View File

@@ -116,7 +116,8 @@ status_t Buffer::initSize(uint32_t w, uint32_t h)
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 @@ status_t Buffer::lock(GGLSurface* sur, uint32_t usage)
sur->stride = stride;
sur->format = format;
sur->vstride = mVStride;
sur->data = static_cast<GGLubyte*>(bits);
sur->data = static_cast<GGLubyte*>(vaddr);
}
return res;
}

View File

@@ -90,23 +90,22 @@ int SurfaceBuffer::getHandle(android_native_buffer_t const * base,
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 @@ static void copyBlt(
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 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
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 @@ status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
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 @@ status_t Surface::unlockAndPost()
mBackbufferIndex, mLockedBuffer->handle);
status_t err = queueBuffer(mLockedBuffer);
mLockedBuffer->bits = NULL;
mLockedBuffer = 0;
return err;
}

View File

@@ -157,9 +157,8 @@ struct android_native_buffer_t
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);

View File

@@ -146,9 +146,10 @@ struct egl_surface_t
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 @@ struct egl_window_surface_v2_t : public egl_surface_t
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 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
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 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
}
}
// 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 @@ status_t egl_window_surface_v2_t::lock(
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 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf)
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 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers()
// 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 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
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 @@ EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
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 @@ struct egl_pixmap_surface_t : public egl_surface_t
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 @@ struct egl_pbuffer_surface_t : public egl_surface_t
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 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
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 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
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 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
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 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
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;

View File

@@ -141,12 +141,13 @@ void ogles_lock_textures(ogles_context_t* c)
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));
}
}