diff options
author | Romain Guy <romainguy@google.com> | 2011-06-14 16:45:55 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2011-06-14 17:06:53 -0700 |
commit | 77a811610f99e21da7f88dafef60d09f345d0506 (patch) | |
tree | f9342ace8ae4541f75c17a3f8531d3c6090de474 /libs/hwui | |
parent | 113543c909baadb911cfda6acef056137e16f191 (diff) | |
download | frameworks_base-77a811610f99e21da7f88dafef60d09f345d0506.zip frameworks_base-77a811610f99e21da7f88dafef60d09f345d0506.tar.gz frameworks_base-77a811610f99e21da7f88dafef60d09f345d0506.tar.bz2 |
Add TextureView.getBitmap()
This API can be used to get a Bitmap copy of the content of a
TextureView.
Change-Id: I07522216c353720fba5cab333174f58f484eb911
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/LayerRenderer.cpp | 90 | ||||
-rw-r--r-- | libs/hwui/LayerRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 16 |
3 files changed, 101 insertions, 8 deletions
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index f316ba7..146e789 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -315,5 +315,95 @@ void LayerRenderer::destroyLayerDeferred(Layer* layer) { } } +bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) { + Caches& caches = Caches::getInstance(); + if (layer && layer->isTextureLayer && bitmap->width() <= caches.maxTextureSize && + bitmap->height() <= caches.maxTextureSize) { + + GLuint fbo = caches.fboCache.get(); + if (!fbo) { + LOGW("Could not obtain an FBO"); + return false; + } + + GLuint texture; + GLuint previousFbo; + + GLenum format; + GLenum type; + + switch (bitmap->config()) { + case SkBitmap::kA8_Config: + format = GL_ALPHA; + type = GL_UNSIGNED_BYTE; + break; + case SkBitmap::kRGB_565_Config: + format = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case SkBitmap::kARGB_4444_Config: + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case SkBitmap::kARGB_8888_Config: + default: + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + break; + } + + glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glGenTextures(1, &texture); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0, format, bitmap->width(), bitmap->height(), + 0, format, type, NULL); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, texture, 0); + + glBindTexture(GL_TEXTURE_2D, layer->texture); + + float alpha = layer->alpha; + SkXfermode::Mode mode = layer->mode; + + layer->mode = SkXfermode::kSrc_Mode; + layer->alpha = 255; + layer->fbo = fbo; + + LayerRenderer renderer(layer); + renderer.setViewport(bitmap->width(), bitmap->height()); + renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f, + bitmap->width(), bitmap->height(), !layer->blend); + + Rect bounds; + bounds.set(0.0f, 0.0f, bitmap->width(), bitmap->height()); + renderer.drawTextureLayer(layer, bounds); + + SkAutoLockPixels alp(*bitmap); + glReadPixels(0, 0, bitmap->width(), bitmap->height(), format, type, bitmap->getPixels()); + + glBindFramebuffer(GL_FRAMEBUFFER, previousFbo); + + layer->mode = mode; + layer->alpha = alpha; + layer->fbo = 0; + glDeleteTextures(1, &texture); + caches.fboCache.put(fbo); + + return true; + } + return false; +} + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h index 59cab96..797dfc6 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -20,6 +20,8 @@ #include "OpenGLRenderer.h" #include "Layer.h" +#include <SkBitmap.h> + namespace android { namespace uirenderer { @@ -60,6 +62,7 @@ public: GLenum renderTarget, float* transform); static void destroyLayer(Layer* layer); static void destroyLayerDeferred(Layer* layer); + static bool copyLayer(Layer* layer, SkBitmap* bitmap); private: void generateMesh(); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index b9e3ddc..0a3d5090 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -178,6 +178,14 @@ protected: return 0; } + /** + * Renders the specified layer as a textured quad. + * + * @param layer The layer to render + * @param rect The bounds of the layer + */ + void drawTextureLayer(Layer* layer, const Rect& rect); + private: /** * Saves the current state of the renderer as a new snapshot. @@ -256,14 +264,6 @@ private: void clearLayerRegions(); /** - * Renders the specified layer as a textured quad. - * - * @param layer The layer to render - * @param rect The bounds of the layer - */ - void drawTextureLayer(Layer* layer, const Rect& rect); - - /** * Mark the layer as dirty at the specified coordinates. The coordinates * are transformed with the supplied matrix. */ |