Loading libs/hwui/OpenGLReadback.cpp +17 −5 Original line number Diff line number Diff line Loading @@ -34,8 +34,6 @@ namespace uirenderer { CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) { ATRACE_CALL(); mRenderThread.eglManager().initialize(); // Setup the source sp<GraphicBuffer> sourceBuffer; sp<Fence> sourceFence; Loading @@ -61,13 +59,19 @@ CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect return CopyResult::Timeout; } return copyGraphicBufferInto(sourceBuffer.get(), texTransform, srcRect, bitmap); } CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap) { mRenderThread.eglManager().initialize(); // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES // to be able to properly sample from the buffer. // Create the EGLImage object that maps the GraphicBuffer EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLClientBuffer clientBuffer = (EGLClientBuffer) sourceBuffer->getNativeBuffer(); EGLClientBuffer clientBuffer = (EGLClientBuffer) graphicBuffer->getNativeBuffer(); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, Loading @@ -78,8 +82,8 @@ CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect return CopyResult::UnknownError; } CopyResult copyResult = copyImageInto(sourceImage, texTransform, sourceBuffer->getWidth(), sourceBuffer->getHeight(), srcRect, bitmap); CopyResult copyResult = copyImageInto(sourceImage, texTransform, graphicBuffer->getWidth(), graphicBuffer->getHeight(), srcRect, bitmap); // All we're flushing & finishing is the deletion of the texture since // copyImageInto already did a major flush & finish as an implicit Loading @@ -89,6 +93,14 @@ CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect return copyResult; } CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) { Rect srcRect; Matrix4 transform; transform.loadScale(1, -1, 1); transform.translate(0, -1); return copyGraphicBufferInto(graphicBuffer, transform, srcRect, bitmap); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Loading libs/hwui/OpenGLReadback.h +5 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ class OpenGLReadback : public Readback { public: virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) override; virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) override; protected: explicit OpenGLReadback(renderthread::RenderThread& thread) : Readback(thread) {} Loading @@ -35,6 +37,9 @@ protected: virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform, int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) = 0; private: CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap); }; class OpenGLReadbackImpl : public OpenGLReadback { Loading libs/hwui/Readback.h +2 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <gui/Surface.h> namespace android { class GraphicBuffer; namespace uirenderer { // Keep in sync with PixelCopy.java codes Loading @@ -42,6 +43,7 @@ public: */ virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) = 0; virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) = 0; protected: explicit Readback(renderthread::RenderThread& thread) : mRenderThread(thread) {} Loading libs/hwui/hwui/Bitmap.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -459,14 +459,15 @@ void Bitmap::setAlphaType(SkAlphaType alphaType) { } void Bitmap::getSkBitmap(SkBitmap* outBitmap) { outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); if (isHardware()) { //TODO: use readback to get pixels LOG_ALWAYS_FATAL("Not implemented"); ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation"); outBitmap->allocPixels(info()); uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap); return; } outBitmap->setInfo(info(), rowBytes()); outBitmap->setPixelRef(this); outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); } void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) { Loading libs/hwui/renderthread/RenderProxy.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include "utils/Macros.h" #include "utils/TimeUtils.h" #include <ui/GraphicBuffer.h> namespace android { namespace uirenderer { namespace renderthread { Loading Loading @@ -663,6 +665,18 @@ sk_sp<Bitmap> RenderProxy::allocateHardwareBitmap(SkBitmap& bitmap) { return hardwareBitmap; } CREATE_BRIDGE3(copyGraphicBufferInto, RenderThread* thread, GraphicBuffer* buffer, SkBitmap* bitmap) { return (void*) args->thread->readback().copyGraphicBufferInto(args->buffer, args->bitmap); } int RenderProxy::copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap) { SETUP_TASK(copyGraphicBufferInto); args->thread = &RenderThread::getInstance(); args->bitmap = bitmap; args->buffer = buffer; return static_cast<int>(reinterpret_cast<intptr_t>(staticPostAndWait(task))); } void RenderProxy::post(RenderTask* task) { mRenderThread.queue(task); } Loading Loading
libs/hwui/OpenGLReadback.cpp +17 −5 Original line number Diff line number Diff line Loading @@ -34,8 +34,6 @@ namespace uirenderer { CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) { ATRACE_CALL(); mRenderThread.eglManager().initialize(); // Setup the source sp<GraphicBuffer> sourceBuffer; sp<Fence> sourceFence; Loading @@ -61,13 +59,19 @@ CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect return CopyResult::Timeout; } return copyGraphicBufferInto(sourceBuffer.get(), texTransform, srcRect, bitmap); } CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap) { mRenderThread.eglManager().initialize(); // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES // to be able to properly sample from the buffer. // Create the EGLImage object that maps the GraphicBuffer EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); EGLClientBuffer clientBuffer = (EGLClientBuffer) sourceBuffer->getNativeBuffer(); EGLClientBuffer clientBuffer = (EGLClientBuffer) graphicBuffer->getNativeBuffer(); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, Loading @@ -78,8 +82,8 @@ CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect return CopyResult::UnknownError; } CopyResult copyResult = copyImageInto(sourceImage, texTransform, sourceBuffer->getWidth(), sourceBuffer->getHeight(), srcRect, bitmap); CopyResult copyResult = copyImageInto(sourceImage, texTransform, graphicBuffer->getWidth(), graphicBuffer->getHeight(), srcRect, bitmap); // All we're flushing & finishing is the deletion of the texture since // copyImageInto already did a major flush & finish as an implicit Loading @@ -89,6 +93,14 @@ CopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect return copyResult; } CopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) { Rect srcRect; Matrix4 transform; transform.loadScale(1, -1, 1); transform.translate(0, -1); return copyGraphicBufferInto(graphicBuffer, transform, srcRect, bitmap); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// Loading
libs/hwui/OpenGLReadback.h +5 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ class OpenGLReadback : public Readback { public: virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) override; virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) override; protected: explicit OpenGLReadback(renderthread::RenderThread& thread) : Readback(thread) {} Loading @@ -35,6 +37,9 @@ protected: virtual CopyResult copyImageInto(EGLImageKHR eglImage, const Matrix4& imgTransform, int imgWidth, int imgHeight, const Rect& srcRect, SkBitmap* bitmap) = 0; private: CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap); }; class OpenGLReadbackImpl : public OpenGLReadback { Loading
libs/hwui/Readback.h +2 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <gui/Surface.h> namespace android { class GraphicBuffer; namespace uirenderer { // Keep in sync with PixelCopy.java codes Loading @@ -42,6 +43,7 @@ public: */ virtual CopyResult copySurfaceInto(Surface& surface, const Rect& srcRect, SkBitmap* bitmap) = 0; virtual CopyResult copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) = 0; protected: explicit Readback(renderthread::RenderThread& thread) : mRenderThread(thread) {} Loading
libs/hwui/hwui/Bitmap.cpp +4 −3 Original line number Diff line number Diff line Loading @@ -459,14 +459,15 @@ void Bitmap::setAlphaType(SkAlphaType alphaType) { } void Bitmap::getSkBitmap(SkBitmap* outBitmap) { outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); if (isHardware()) { //TODO: use readback to get pixels LOG_ALWAYS_FATAL("Not implemented"); ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation"); outBitmap->allocPixels(info()); uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap); return; } outBitmap->setInfo(info(), rowBytes()); outBitmap->setPixelRef(this); outBitmap->setHasHardwareMipMap(mHasHardwareMipMap); } void Bitmap::getSkBitmapForShaders(SkBitmap* outBitmap) { Loading
libs/hwui/renderthread/RenderProxy.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include "utils/Macros.h" #include "utils/TimeUtils.h" #include <ui/GraphicBuffer.h> namespace android { namespace uirenderer { namespace renderthread { Loading Loading @@ -663,6 +665,18 @@ sk_sp<Bitmap> RenderProxy::allocateHardwareBitmap(SkBitmap& bitmap) { return hardwareBitmap; } CREATE_BRIDGE3(copyGraphicBufferInto, RenderThread* thread, GraphicBuffer* buffer, SkBitmap* bitmap) { return (void*) args->thread->readback().copyGraphicBufferInto(args->buffer, args->bitmap); } int RenderProxy::copyGraphicBufferInto(GraphicBuffer* buffer, SkBitmap* bitmap) { SETUP_TASK(copyGraphicBufferInto); args->thread = &RenderThread::getInstance(); args->bitmap = bitmap; args->buffer = buffer; return static_cast<int>(reinterpret_cast<intptr_t>(staticPostAndWait(task))); } void RenderProxy::post(RenderTask* task) { mRenderThread.queue(task); } Loading