Loading libs/surfaceflinger/LayerBuffer.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -341,6 +341,9 @@ LayerBuffer::BufferSource::~BufferSource() if (mTexture.name != -1U) { glDeleteTextures(1, &mTexture.name); } if (mBlitEngine) { copybit_close(mBlitEngine); } } void LayerBuffer::BufferSource::postBuffer(ssize_t offset) Loading opengl/libagl/egl.cpp +109 −52 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include <private/ui/android_natives_priv.h> #include <hardware/copybit.h> #include "context.h" #include "state.h" #include "texture.h" Loading Loading @@ -234,6 +236,7 @@ private: android_native_buffer_t* buffer; android_native_buffer_t* previousBuffer; gralloc_module_t const* module; copybit_device_t* blitengine; int width; int height; void* bits; Loading Loading @@ -268,6 +271,9 @@ private: struct Region { inline Region() : count(0) { } typedef Rect const* const_iterator; const_iterator begin() const { return storage; } const_iterator end() const { return storage+count; } static Region subtract(const Rect& lhs, const Rect& rhs) { Region reg; Rect* storage = reg.storage; Loading @@ -276,26 +282,30 @@ private: storage->left = lhs.left; storage->top = lhs.top; storage->right = lhs.right; storage->bottom = max(lhs.top, rhs.top); storage->bottom = rhs.top; storage++; } const int32_t top = max(lhs.top, rhs.top); const int32_t bot = min(lhs.bottom, rhs.bottom); if (top < bot) { if (lhs.left < rhs.left) { // left-side rect storage->left = lhs.left; storage->top = max(lhs.top, rhs.top); storage->right = max(lhs.left, rhs.left); storage->bottom = min(lhs.bottom, rhs.bottom); storage->top = top; storage->right = rhs.left; storage->bottom = bot; storage++; } if (lhs.right > rhs.right) { // right-side rect storage->left = min(lhs.right, rhs.right); storage->top = max(lhs.top, rhs.top); storage->left = rhs.right; storage->top = top; storage->right = lhs.right; storage->bottom = min(lhs.bottom, rhs.bottom); storage->bottom = bot; storage++; } } if (lhs.bottom > rhs.bottom) { // bottom rect storage->left = lhs.left; storage->top = min(lhs.bottom, rhs.bottom); storage->top = rhs.bottom; storage->right = lhs.right; storage->bottom = lhs.bottom; storage++; Loading @@ -307,19 +317,33 @@ private: bool isEmpty() const { return count<=0; } ssize_t getRects(Rect const* * rects) const { *rects = storage; return count; } private: Rect storage[4]; ssize_t count; }; struct region_iterator : public copybit_region_t { region_iterator(const Region& region) : b(region.begin()), e(region.end()) { this->next = iterate; } private: static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { region_iterator const* me = static_cast<region_iterator const*>(self); if (me->b != me->e) { *reinterpret_cast<Rect*>(rect) = *me->b++; return 1; } return 0; } mutable Region::const_iterator b; Region::const_iterator const e; }; void copyBlt( android_native_buffer_t* dst, void* dst_vaddr, android_native_buffer_t* src, void const* src_vaddr, const Rect* reg, ssize_t count); const Region& clip); Rect dirtyRegion; Rect oldDirtyRegion; Loading @@ -331,12 +355,16 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, android_native_window_t* window) : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0), previousBuffer(0), module(0), bits(NULL) blitengine(0), bits(NULL) { hw_module_t const* pModule; hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); module = reinterpret_cast<gralloc_module_t const*>(pModule); if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &pModule) == 0) { copybit_open(pModule, &blitengine); } pixelFormatTable = gglGetPixelFormatTable(); // keep a reference on the window Loading Loading @@ -371,6 +399,9 @@ egl_window_surface_v2_t::~egl_window_surface_v2_t() { previousBuffer->common.decRef(&previousBuffer->common); } nativeWindow->common.decRef(&nativeWindow->common); if (blitengine) { copybit_close(blitengine); } } void egl_window_surface_v2_t::connect() Loading @@ -380,7 +411,7 @@ void egl_window_surface_v2_t::connect() // pin the buffer down if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", LOGE("connect() failed to lock buffer %p (%ux%u)", buffer, buffer->width, buffer->height); setError(EGL_BAD_ACCESS, EGL_NO_SURFACE); // FIXME: we should make sure we're not accessing the buffer anymore Loading Loading @@ -412,12 +443,40 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) void egl_window_surface_v2_t::copyBlt( android_native_buffer_t* dst, void* dst_vaddr, android_native_buffer_t* src, void const* src_vaddr, const Rect* reg, ssize_t count) const Region& clip) { // FIXME: use copybit if possible // NOTE: dst and src must be the same format Rect r; status_t err = NO_ERROR; copybit_device_t* const copybit = blitengine; if (copybit) { copybit_image_t simg; simg.w = src->width; simg.h = src->height; simg.format = src->format; simg.handle = const_cast<native_handle_t*>(src->handle); copybit_image_t dimg; dimg.w = dst->width; dimg.h = dst->height; dimg.format = dst->format; dimg.handle = const_cast<native_handle_t*>(dst->handle); copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); region_iterator it(clip); err = copybit->blit(copybit, &dimg, &simg, &it); if (err != NO_ERROR) { LOGE("copybit failed (%s)", strerror(err)); } } if (!copybit || err) { Region::const_iterator cur = clip.begin(); Region::const_iterator end = clip.end(); const size_t bpp = pixelFormatTable[src->format].size; const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; Loading @@ -425,8 +484,8 @@ void egl_window_surface_v2_t::copyBlt( uint8_t const * const src_bits = (uint8_t const *)src_vaddr; uint8_t * const dst_bits = (uint8_t *)dst_vaddr; for (int i= 0 ; i<count ; i++) { const Rect& r(reg[i]); while (cur != end) { const Rect& r(*cur++); ssize_t w = r.right - r.left; ssize_t h = r.bottom - r.top; if (w <= 0 || h<=0) continue; Loading @@ -444,6 +503,7 @@ void egl_window_surface_v2_t::copyBlt( } while (--h > 0); } } } EGLBoolean egl_window_surface_v2_t::swapBuffers() { Loading @@ -456,14 +516,11 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() if (previousBuffer) { const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); if (!copyBack.isEmpty()) { Rect const* list; ssize_t count = copyBack.getRects(&list); // copy from previousBuffer to buffer void* prevBits; if (lock(previousBuffer, GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) { copyBlt(buffer, bits, previousBuffer, prevBits, list, count); GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) { // copy from previousBuffer to buffer copyBlt(buffer, bits, previousBuffer, prevBits, copyBack); unlock(previousBuffer); } } Loading Loading
libs/surfaceflinger/LayerBuffer.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -341,6 +341,9 @@ LayerBuffer::BufferSource::~BufferSource() if (mTexture.name != -1U) { glDeleteTextures(1, &mTexture.name); } if (mBlitEngine) { copybit_close(mBlitEngine); } } void LayerBuffer::BufferSource::postBuffer(ssize_t offset) Loading
opengl/libagl/egl.cpp +109 −52 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ #include <private/ui/android_natives_priv.h> #include <hardware/copybit.h> #include "context.h" #include "state.h" #include "texture.h" Loading Loading @@ -234,6 +236,7 @@ private: android_native_buffer_t* buffer; android_native_buffer_t* previousBuffer; gralloc_module_t const* module; copybit_device_t* blitengine; int width; int height; void* bits; Loading Loading @@ -268,6 +271,9 @@ private: struct Region { inline Region() : count(0) { } typedef Rect const* const_iterator; const_iterator begin() const { return storage; } const_iterator end() const { return storage+count; } static Region subtract(const Rect& lhs, const Rect& rhs) { Region reg; Rect* storage = reg.storage; Loading @@ -276,26 +282,30 @@ private: storage->left = lhs.left; storage->top = lhs.top; storage->right = lhs.right; storage->bottom = max(lhs.top, rhs.top); storage->bottom = rhs.top; storage++; } const int32_t top = max(lhs.top, rhs.top); const int32_t bot = min(lhs.bottom, rhs.bottom); if (top < bot) { if (lhs.left < rhs.left) { // left-side rect storage->left = lhs.left; storage->top = max(lhs.top, rhs.top); storage->right = max(lhs.left, rhs.left); storage->bottom = min(lhs.bottom, rhs.bottom); storage->top = top; storage->right = rhs.left; storage->bottom = bot; storage++; } if (lhs.right > rhs.right) { // right-side rect storage->left = min(lhs.right, rhs.right); storage->top = max(lhs.top, rhs.top); storage->left = rhs.right; storage->top = top; storage->right = lhs.right; storage->bottom = min(lhs.bottom, rhs.bottom); storage->bottom = bot; storage++; } } if (lhs.bottom > rhs.bottom) { // bottom rect storage->left = lhs.left; storage->top = min(lhs.bottom, rhs.bottom); storage->top = rhs.bottom; storage->right = lhs.right; storage->bottom = lhs.bottom; storage++; Loading @@ -307,19 +317,33 @@ private: bool isEmpty() const { return count<=0; } ssize_t getRects(Rect const* * rects) const { *rects = storage; return count; } private: Rect storage[4]; ssize_t count; }; struct region_iterator : public copybit_region_t { region_iterator(const Region& region) : b(region.begin()), e(region.end()) { this->next = iterate; } private: static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { region_iterator const* me = static_cast<region_iterator const*>(self); if (me->b != me->e) { *reinterpret_cast<Rect*>(rect) = *me->b++; return 1; } return 0; } mutable Region::const_iterator b; Region::const_iterator const e; }; void copyBlt( android_native_buffer_t* dst, void* dst_vaddr, android_native_buffer_t* src, void const* src_vaddr, const Rect* reg, ssize_t count); const Region& clip); Rect dirtyRegion; Rect oldDirtyRegion; Loading @@ -331,12 +355,16 @@ egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, android_native_window_t* window) : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0), previousBuffer(0), module(0), bits(NULL) blitengine(0), bits(NULL) { hw_module_t const* pModule; hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule); module = reinterpret_cast<gralloc_module_t const*>(pModule); if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &pModule) == 0) { copybit_open(pModule, &blitengine); } pixelFormatTable = gglGetPixelFormatTable(); // keep a reference on the window Loading Loading @@ -371,6 +399,9 @@ egl_window_surface_v2_t::~egl_window_surface_v2_t() { previousBuffer->common.decRef(&previousBuffer->common); } nativeWindow->common.decRef(&nativeWindow->common); if (blitengine) { copybit_close(blitengine); } } void egl_window_surface_v2_t::connect() Loading @@ -380,7 +411,7 @@ void egl_window_surface_v2_t::connect() // pin the buffer down if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", LOGE("connect() failed to lock buffer %p (%ux%u)", buffer, buffer->width, buffer->height); setError(EGL_BAD_ACCESS, EGL_NO_SURFACE); // FIXME: we should make sure we're not accessing the buffer anymore Loading Loading @@ -412,12 +443,40 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) void egl_window_surface_v2_t::copyBlt( android_native_buffer_t* dst, void* dst_vaddr, android_native_buffer_t* src, void const* src_vaddr, const Rect* reg, ssize_t count) const Region& clip) { // FIXME: use copybit if possible // NOTE: dst and src must be the same format Rect r; status_t err = NO_ERROR; copybit_device_t* const copybit = blitengine; if (copybit) { copybit_image_t simg; simg.w = src->width; simg.h = src->height; simg.format = src->format; simg.handle = const_cast<native_handle_t*>(src->handle); copybit_image_t dimg; dimg.w = dst->width; dimg.h = dst->height; dimg.format = dst->format; dimg.handle = const_cast<native_handle_t*>(dst->handle); copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); region_iterator it(clip); err = copybit->blit(copybit, &dimg, &simg, &it); if (err != NO_ERROR) { LOGE("copybit failed (%s)", strerror(err)); } } if (!copybit || err) { Region::const_iterator cur = clip.begin(); Region::const_iterator end = clip.end(); const size_t bpp = pixelFormatTable[src->format].size; const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; Loading @@ -425,8 +484,8 @@ void egl_window_surface_v2_t::copyBlt( uint8_t const * const src_bits = (uint8_t const *)src_vaddr; uint8_t * const dst_bits = (uint8_t *)dst_vaddr; for (int i= 0 ; i<count ; i++) { const Rect& r(reg[i]); while (cur != end) { const Rect& r(*cur++); ssize_t w = r.right - r.left; ssize_t h = r.bottom - r.top; if (w <= 0 || h<=0) continue; Loading @@ -444,6 +503,7 @@ void egl_window_surface_v2_t::copyBlt( } while (--h > 0); } } } EGLBoolean egl_window_surface_v2_t::swapBuffers() { Loading @@ -456,14 +516,11 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() if (previousBuffer) { const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); if (!copyBack.isEmpty()) { Rect const* list; ssize_t count = copyBack.getRects(&list); // copy from previousBuffer to buffer void* prevBits; if (lock(previousBuffer, GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) { copyBlt(buffer, bits, previousBuffer, prevBits, list, count); GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) { // copy from previousBuffer to buffer copyBlt(buffer, bits, previousBuffer, prevBits, copyBack); unlock(previousBuffer); } } Loading