Loading libs/hwui/GlopBuilder.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -471,6 +471,21 @@ GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) { return *this; } GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage | kRoundRectClipStage); mOutGlop->fill.texture = { &texture, GL_TEXTURE_EXTERNAL_OES, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr }; setFill(SK_ColorWHITE, 1.0f, SkXfermode::kSrc_Mode, Blend::ModeOrderSwap::NoSwap, nullptr, nullptr); mDescription.modulate = mOutGlop->fill.color.a < 1.0f; return *this; } //////////////////////////////////////////////////////////////////////////////// // Transform //////////////////////////////////////////////////////////////////////////////// Loading libs/hwui/GlopBuilder.h +4 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,10 @@ public: GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter, float alpha, SkXfermode::Mode mode, Blend::ModeOrderSwap modeUsage); GlopBuilder& setFillTextureLayer(Layer& layer, float alpha); // TODO: Texture should probably know and own its target. // setFillLayer() forces it to GL_TEXTURE which isn't always correct. // Similarly setFillLayer normally forces its own wrap & filter mode GlopBuilder& setFillExternalTexture(Texture& texture); GlopBuilder& setTransform(const Snapshot& snapshot, const int transformFlags) { return setTransform(*snapshot.transform, transformFlags); Loading libs/hwui/Readback.cpp +35 −9 Original line number Diff line number Diff line Loading @@ -101,24 +101,51 @@ bool Readback::copySurfaceInto(renderthread::RenderThread& renderThread, // Setup the source sp<GraphicBuffer> sourceBuffer; sp<Fence> sourceFence; // FIXME: Waiting on an API from libgui for this // surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence); status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence); if (err != NO_ERROR) { ALOGW("Failed to get last queued buffer, error = %d", err); return false; } if (!sourceBuffer.get()) { ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); return false; } int err = sourceFence->wait(500 /* ms */); err = sourceFence->wait(500 /* ms */); if (err != NO_ERROR) { ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); return false; } Image sourceImage(sourceBuffer); if (!sourceImage.getTexture()) { ALOGW("Failed to make an EGLImage from the GraphicBuffer"); // 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(); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs); if (sourceImage == EGL_NO_IMAGE_KHR) { ALOGW("Error creating image (%#x)", eglGetError()); return false; } GLuint sourceTexId; // Create a 2D texture to sample from the EGLImage glGenTextures(1, &sourceTexId); Caches::getInstance().textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId); glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, sourceImage); GLenum status = GL_NO_ERROR; while ((status = glGetError()) != GL_NO_ERROR) { ALOGW("Error creating image (%#x)", status); return false; } Texture sourceTexture(caches); sourceTexture.wrap(sourceImage.getTexture(), sourceTexture.wrap(sourceTexId, sourceBuffer->getWidth(), sourceBuffer->getHeight(), 0 /* total lie */); { Loading @@ -133,8 +160,7 @@ bool Readback::copySurfaceInto(renderthread::RenderThread& renderThread, GlopBuilder(renderState, caches, &glop) .setRoundRectClipState(nullptr) .setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO .setFillLayer(sourceTexture, nullptr, 1.0f, SkXfermode::kSrc_Mode, Blend::ModeOrderSwap::NoSwap) .setFillExternalTexture(sourceTexture) .setTransform(Matrix4::identity(), TransformFlags::None) .setModelViewMapUnitToRect(destRect) .build(); Loading Loading
libs/hwui/GlopBuilder.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -471,6 +471,21 @@ GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) { return *this; } GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage | kRoundRectClipStage); mOutGlop->fill.texture = { &texture, GL_TEXTURE_EXTERNAL_OES, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr }; setFill(SK_ColorWHITE, 1.0f, SkXfermode::kSrc_Mode, Blend::ModeOrderSwap::NoSwap, nullptr, nullptr); mDescription.modulate = mOutGlop->fill.color.a < 1.0f; return *this; } //////////////////////////////////////////////////////////////////////////////// // Transform //////////////////////////////////////////////////////////////////////////////// Loading
libs/hwui/GlopBuilder.h +4 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,10 @@ public: GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter, float alpha, SkXfermode::Mode mode, Blend::ModeOrderSwap modeUsage); GlopBuilder& setFillTextureLayer(Layer& layer, float alpha); // TODO: Texture should probably know and own its target. // setFillLayer() forces it to GL_TEXTURE which isn't always correct. // Similarly setFillLayer normally forces its own wrap & filter mode GlopBuilder& setFillExternalTexture(Texture& texture); GlopBuilder& setTransform(const Snapshot& snapshot, const int transformFlags) { return setTransform(*snapshot.transform, transformFlags); Loading
libs/hwui/Readback.cpp +35 −9 Original line number Diff line number Diff line Loading @@ -101,24 +101,51 @@ bool Readback::copySurfaceInto(renderthread::RenderThread& renderThread, // Setup the source sp<GraphicBuffer> sourceBuffer; sp<Fence> sourceFence; // FIXME: Waiting on an API from libgui for this // surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence); status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence); if (err != NO_ERROR) { ALOGW("Failed to get last queued buffer, error = %d", err); return false; } if (!sourceBuffer.get()) { ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); return false; } int err = sourceFence->wait(500 /* ms */); err = sourceFence->wait(500 /* ms */); if (err != NO_ERROR) { ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); return false; } Image sourceImage(sourceBuffer); if (!sourceImage.getTexture()) { ALOGW("Failed to make an EGLImage from the GraphicBuffer"); // 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(); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs); if (sourceImage == EGL_NO_IMAGE_KHR) { ALOGW("Error creating image (%#x)", eglGetError()); return false; } GLuint sourceTexId; // Create a 2D texture to sample from the EGLImage glGenTextures(1, &sourceTexId); Caches::getInstance().textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId); glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, sourceImage); GLenum status = GL_NO_ERROR; while ((status = glGetError()) != GL_NO_ERROR) { ALOGW("Error creating image (%#x)", status); return false; } Texture sourceTexture(caches); sourceTexture.wrap(sourceImage.getTexture(), sourceTexture.wrap(sourceTexId, sourceBuffer->getWidth(), sourceBuffer->getHeight(), 0 /* total lie */); { Loading @@ -133,8 +160,7 @@ bool Readback::copySurfaceInto(renderthread::RenderThread& renderThread, GlopBuilder(renderState, caches, &glop) .setRoundRectClipState(nullptr) .setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO .setFillLayer(sourceTexture, nullptr, 1.0f, SkXfermode::kSrc_Mode, Blend::ModeOrderSwap::NoSwap) .setFillExternalTexture(sourceTexture) .setTransform(Matrix4::identity(), TransformFlags::None) .setModelViewMapUnitToRect(destRect) .build(); Loading