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
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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
}
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 @@
{
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 @@
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 @@
}
} 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 @@
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::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 @@
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 @@
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 GraphicPlane;
class Client;
class SurfaceBuffer;
+class Buffer;
// ---------------------------------------------------------------------------
@@ -239,7 +240,7 @@
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()
{
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 @@
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 @@
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 @@
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 @@
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 @@
SurfaceFlinger::~SurfaceFlinger()
{
glDeleteTextures(1, &mWormholeTexName);
- delete mOrientationAnimation;
}
overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
@@ -399,8 +396,6 @@
* 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 @@
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 @@
mVisibleRegionsDirty = true;
mDirtyRegion.set(hw.bounds());
mFreezeDisplayTime = 0;
- mOrientationAnimation->onOrientationChanged(type);
}
if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
@@ -893,19 +888,26 @@
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 @@
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 FreezeLock;
class Layer;
class LayerBuffer;
-class LayerOrientationAnim;
-class OrientationAnimation;
typedef int32_t ClientID;
@@ -335,8 +333,6 @@
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
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnim.cpp
rename to libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnim.h
rename to libs/surfaceflinger/purgatory/LayerOrientationAnim.h
diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnimRotate.cpp
rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnimRotate.h
rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp
similarity index 100%
rename from libs/surfaceflinger/OrientationAnimation.cpp
rename to libs/surfaceflinger/purgatory/OrientationAnimation.cpp
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h
similarity index 100%
rename from libs/surfaceflinger/OrientationAnimation.h
rename to 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 @@
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 @@
}
}
-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 @@
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
similarity index 81%
rename from libs/ui/EGLNativeWindowSurface.cpp
rename to 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 @@
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 @@
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() {
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 @@
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 @@
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 @@
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 @@
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 @@
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(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 @@
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 @@
// ----------------------------------------------------------------------
-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 @@
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 @@
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 @@
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 @@
// 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 @@
// ----------------------------------------------------------------------------
-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 @@
// ----------------------------------------------------------------------------
+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 @@
}
const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
+ mDirtyRegion.set(backBuffer->width, backBuffer->height);
*buffer = backBuffer.get();
-
+
return NO_ERROR;
}
@@ -542,11 +571,14 @@
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 @@
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 @@
// 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 @@
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 @@
}
}
-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 @@
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;