OpenGLReadback.cpp revision 912bebeb7488f498954282a1eb82a4b641e6418e
110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck/* 210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * Copyright (C) 2016 The Android Open Source Project 310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * 410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * Licensed under the Apache License, Version 2.0 (the "License"); 510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * you may not use this file except in compliance with the License. 610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * You may obtain a copy of the License at 710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * 810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * http://www.apache.org/licenses/LICENSE-2.0 910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * 1010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * Unless required by applicable law or agreed to in writing, software 1110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * distributed under the License is distributed on an "AS IS" BASIS, 1210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * See the License for the specific language governing permissions and 1410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck * limitations under the License. 1510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck */ 1610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 17c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger#include "OpenGLReadback.h" 1810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 1910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include "Caches.h" 2010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include "Image.h" 2110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include "GlopBuilder.h" 22764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik#include "Layer.h" 2310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include "renderstate/RenderState.h" 2410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include "renderthread/EglManager.h" 2510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include "utils/GLUtils.h" 2610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 2710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include <GLES2/gl2.h> 2810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include <ui/Fence.h> 2910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck#include <ui/GraphicBuffer.h> 3010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 3110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Recknamespace android { 3210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Recknamespace uirenderer { 3310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 34c4fbada76aa840105553b2c2bce2204e673d2983Derek SollenbergerCopyResult OpenGLReadback::copySurfaceInto(Surface& surface, const Rect& srcRect, 35c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger SkBitmap* bitmap) { 36c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger ATRACE_CALL(); 37c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // Setup the source 38c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger sp<GraphicBuffer> sourceBuffer; 39c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger sp<Fence> sourceFence; 40c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger Matrix4 texTransform; 41c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger status_t err = surface.getLastQueuedBuffer(&sourceBuffer, &sourceFence, 42c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger texTransform.data); 43c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger texTransform.invalidateType(); 44c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger if (err != NO_ERROR) { 45c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger ALOGW("Failed to get last queued buffer, error = %d", err); 46c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return CopyResult::UnknownError; 47c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger } 48c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger if (!sourceBuffer.get()) { 49c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger ALOGW("Surface doesn't have any previously queued frames, nothing to readback from"); 50c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return CopyResult::SourceEmpty; 51c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger } 52c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger if (sourceBuffer->getUsage() & GRALLOC_USAGE_PROTECTED) { 53c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger ALOGW("Surface is protected, unable to copy from it"); 54c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return CopyResult::SourceInvalid; 55c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger } 56c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger err = sourceFence->wait(500 /* ms */); 57c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger if (err != NO_ERROR) { 58c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger ALOGE("Timeout (500ms) exceeded waiting for buffer fence, abandoning readback attempt"); 59c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return CopyResult::Timeout; 60c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger } 61c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 6259eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv return copyGraphicBufferInto(sourceBuffer.get(), texTransform, srcRect, bitmap); 6359eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv} 6459eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv 6559eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyvCopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, 6659eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv Matrix4& texTransform, const Rect& srcRect, SkBitmap* bitmap) { 6759eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv mRenderThread.eglManager().initialize(); 68c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via 69c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES 70c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // to be able to properly sample from the buffer. 71c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 72c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // Create the EGLImage object that maps the GraphicBuffer 73c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 7459eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv EGLClientBuffer clientBuffer = (EGLClientBuffer) graphicBuffer->getNativeBuffer(); 75c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; 76c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 77c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger EGLImageKHR sourceImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, 78c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs); 79c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 80c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger if (sourceImage == EGL_NO_IMAGE_KHR) { 81c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger ALOGW("eglCreateImageKHR failed (%#x)", eglGetError()); 82c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return CopyResult::UnknownError; 83c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger } 84c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 85912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck uint32_t width = graphicBuffer->getWidth(); 86912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck uint32_t height = graphicBuffer->getHeight(); 87912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck // If this is a 90 or 270 degree rotation we need to swap width/height 88912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck // This is a fuzzy way of checking that. 89912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck if (texTransform[Matrix4::kSkewX] >= 0.5f || texTransform[Matrix4::kSkewX] <= -0.5f) { 90912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck std::swap(width, height); 91912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck } 92912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck CopyResult copyResult = copyImageInto(sourceImage, texTransform, width, height, 93912bebeb7488f498954282a1eb82a4b641e6418eJohn Reck srcRect, bitmap); 94c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 95c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // All we're flushing & finishing is the deletion of the texture since 96c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // copyImageInto already did a major flush & finish as an implicit 97c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger // part of glReadPixels, so this shouldn't pose any major stalls. 98c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger glFinish(); 99c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger eglDestroyImageKHR(display, sourceImage); 100c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return copyResult; 101c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger} 102c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 10359eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyvCopyResult OpenGLReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer, SkBitmap* bitmap) { 10459eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv Rect srcRect; 10559eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv Matrix4 transform; 10659eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv transform.loadScale(1, -1, 1); 10759eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv transform.translate(0, -1); 10859eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv return copyGraphicBufferInto(graphicBuffer, transform, srcRect, bitmap); 10959eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv} 11059eecb526adc5bd7041e7b6147bfcc40dd2c200esergeyv 111c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 112c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger//////////////////////////////////////////////////////////////////////////////// 113c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 114c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenbergerinline CopyResult copyTextureInto(Caches& caches, RenderState& renderState, 115c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger Texture& sourceTexture, const Matrix4& texTransform, const Rect& srcRect, 1169580146f5076aaa7c498f86bd3d724c00599f6f4John Reck SkBitmap* bitmap) { 11710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck int destWidth = bitmap->width(); 11810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck int destHeight = bitmap->height(); 11910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck if (destWidth > caches.maxTextureSize 12010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck || destHeight > caches.maxTextureSize) { 12110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck ALOGW("Can't copy surface into bitmap, %dx%d exceeds max texture size %d", 12210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck destWidth, destHeight, caches.maxTextureSize); 123e94cbc76d560a157c0a0d47181b4ed2a0aadbeb1John Reck return CopyResult::DestinationInvalid; 12410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck } 12510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck GLuint fbo = renderState.createFramebuffer(); 12610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck if (!fbo) { 12710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck ALOGW("Could not obtain an FBO"); 128e94cbc76d560a157c0a0d47181b4ed2a0aadbeb1John Reck return CopyResult::UnknownError; 12910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck } 13010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 13110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck SkAutoLockPixels alp(*bitmap); 13210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 13310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck GLuint texture; 13410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 13510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck GLenum format; 13610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck GLenum type; 13710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 13810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck switch (bitmap->colorType()) { 13910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck case kAlpha_8_SkColorType: 14010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck format = GL_ALPHA; 14110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck type = GL_UNSIGNED_BYTE; 14210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck break; 14310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck case kRGB_565_SkColorType: 14410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck format = GL_RGB; 14510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck type = GL_UNSIGNED_SHORT_5_6_5; 14610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck break; 14710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck case kARGB_4444_SkColorType: 14810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck format = GL_RGBA; 14910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck type = GL_UNSIGNED_SHORT_4_4_4_4; 15010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck break; 15110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck case kN32_SkColorType: 15210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck default: 15310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck format = GL_RGBA; 15410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck type = GL_UNSIGNED_BYTE; 15510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck break; 15610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck } 15710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 15810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck renderState.bindFramebuffer(fbo); 15910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 16010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck // TODO: Use layerPool or something to get this maybe? But since we 16110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck // need explicit format control we can't currently. 16210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 16310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck // Setup the rendertarget 16410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glGenTextures(1, &texture); 16510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck caches.textureState().activateTexture(0); 16610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck caches.textureState().bindTexture(texture); 16710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glPixelStorei(GL_PACK_ALIGNMENT, bitmap->bytesPerPixel()); 16810dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 16910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 17010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 17110dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 17210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glTexImage2D(GL_TEXTURE_2D, 0, format, destWidth, destHeight, 17310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 0, format, type, nullptr); 17410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 17510dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck GL_TEXTURE_2D, texture, 0); 17610dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 177764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik { 178764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik // Draw & readback 179764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik renderState.setViewport(destWidth, destHeight); 180764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik renderState.scissor().setEnabled(false); 181764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik renderState.blend().syncEnabled(); 182764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik renderState.stencil().disable(); 183764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 1849580146f5076aaa7c498f86bd3d724c00599f6f4John Reck Matrix4 croppedTexTransform(texTransform); 1859580146f5076aaa7c498f86bd3d724c00599f6f4John Reck if (!srcRect.isEmpty()) { 1869580146f5076aaa7c498f86bd3d724c00599f6f4John Reck croppedTexTransform.loadTranslate(srcRect.left / sourceTexture.width(), 1879580146f5076aaa7c498f86bd3d724c00599f6f4John Reck srcRect.top / sourceTexture.height(), 0); 1889580146f5076aaa7c498f86bd3d724c00599f6f4John Reck croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(), 1899580146f5076aaa7c498f86bd3d724c00599f6f4John Reck srcRect.getHeight() / sourceTexture.height(), 1); 1909580146f5076aaa7c498f86bd3d724c00599f6f4John Reck croppedTexTransform.multiply(texTransform); 1919580146f5076aaa7c498f86bd3d724c00599f6f4John Reck } 192764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik Glop glop; 193764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik GlopBuilder(renderState, caches, &glop) 194764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik .setRoundRectClipState(nullptr) 195764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik .setMeshTexturedUnitQuad(nullptr) 1969580146f5076aaa7c498f86bd3d724c00599f6f4John Reck .setFillExternalTexture(sourceTexture, croppedTexTransform) 197764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik .setTransform(Matrix4::identity(), TransformFlags::None) 198764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik .setModelViewMapUnitToRect(Rect(destWidth, destHeight)) 199764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik .build(); 200764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik Matrix4 ortho; 201764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik ortho.loadOrtho(destWidth, destHeight); 202764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik renderState.render(glop, ortho); 203764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 204764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik glReadPixels(0, 0, bitmap->width(), bitmap->height(), format, 205764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik type, bitmap->getPixels()); 206764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik } 207764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 208764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik // Cleanup 209764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik caches.textureState().deleteTexture(texture); 210764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik renderState.deleteFramebuffer(fbo); 211764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 212764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik GL_CHECKPOINT(MODERATE); 213764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 214764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik return CopyResult::Success; 215764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik} 216764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 217c4fbada76aa840105553b2c2bce2204e673d2983Derek SollenbergerCopyResult OpenGLReadbackImpl::copyImageInto(EGLImageKHR eglImage, 218c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger const Matrix4& imgTransform, int imgWidth, int imgHeight, const Rect& srcRect, 219c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger SkBitmap* bitmap) { 220764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik 221764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik Caches& caches = Caches::getInstance(); 2222f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck GLuint sourceTexId; 2232f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck // Create a 2D texture to sample from the EGLImage 2242f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck glGenTextures(1, &sourceTexId); 225764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik caches.textureState().bindTexture(GL_TEXTURE_EXTERNAL_OES, sourceTexId); 226c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImage); 2272f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck 2282f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck GLenum status = GL_NO_ERROR; 2292f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck while ((status = glGetError()) != GL_NO_ERROR) { 2308a29c0ec86a9411a07bb10018c3da69fffc0fe7dJohn Reck ALOGW("glEGLImageTargetTexture2DOES failed (%#x)", status); 231e94cbc76d560a157c0a0d47181b4ed2a0aadbeb1John Reck return CopyResult::UnknownError; 23210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck } 2332f78327cfcd4c7b23aae9bb0262e64050d093a64John Reck 23410dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck Texture sourceTexture(caches); 235c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger sourceTexture.wrap(sourceTexId, imgWidth, imgHeight, 0, 0 /* total lie */, 236c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger GL_TEXTURE_EXTERNAL_OES); 23710dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 238c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger CopyResult copyResult = copyTextureInto(caches, mRenderThread.renderState(), 239c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger sourceTexture, imgTransform, srcRect, bitmap); 2408a29c0ec86a9411a07bb10018c3da69fffc0fe7dJohn Reck sourceTexture.deleteTexture(); 2418a29c0ec86a9411a07bb10018c3da69fffc0fe7dJohn Reck return copyResult; 242764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik} 24310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 244c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenbergerbool OpenGLReadbackImpl::copyLayerInto(renderthread::RenderThread& renderThread, 245764045da2ce980f1eee78171de5b4f09dfb601a7Chris Craik Layer& layer, SkBitmap* bitmap) { 246c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger return CopyResult::Success == copyTextureInto(Caches::getInstance(), 247c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger renderThread.renderState(), layer.getTexture(), layer.getTexTransform(), 248c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger Rect(), bitmap); 24910dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck} 25010dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck 251c4fbada76aa840105553b2c2bce2204e673d2983Derek Sollenberger 25210dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck} // namespace uirenderer 25310dd0585c11dcedb5a271d54e645594f1d215d5cJohn Reck} // namespace android 254