summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-06-14 16:45:55 -0700
committerRomain Guy <romainguy@google.com>2011-06-14 17:06:53 -0700
commit77a811610f99e21da7f88dafef60d09f345d0506 (patch)
treef9342ace8ae4541f75c17a3f8531d3c6090de474 /libs
parent113543c909baadb911cfda6acef056137e16f191 (diff)
downloadframeworks_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')
-rw-r--r--libs/hwui/LayerRenderer.cpp90
-rw-r--r--libs/hwui/LayerRenderer.h3
-rw-r--r--libs/hwui/OpenGLRenderer.h16
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.
*/