Merge "PixelCopy fixes" into nyc-dev am: a5bbbe5
am: d928ad6 * commit 'd928ad61e87ce8ecc1a7edae26bced459c923859': PixelCopy fixes Change-Id: Iaae3de7f8fd4b90856006bd7e4d3823a61168810
This commit is contained in:
@@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */);
|
||||
|
||||
{
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user