New widget: TextureView
Bug #4343984
TextureView can be used to render media content (video, OpenGL,
RenderScript) inside a View.
The key difference with SurfaceView is that TextureView does
not create a new Surface. This gives the ability to seamlessly
transform, animate, fade, etc. a TextureView, which was hard
if not impossible to do with a SurfaceView.
A TextureView also interacts perfectly with ScrollView,
ListView, etc. It allows application to embed media content
in a much more flexible way than before.
For instance, to render the camera preview at 50% opacity,
all you need to do is the following:
mTextureView.setAlpha(0.5f);
Camera c = Camera.open();
c.setPreviewTexture(mTextureView.getSurfaceTexture());
c.startPreview();
TextureView uses a SurfaceTexture to get the job done. More
APIs are required to make it easy to create OpenGL contexts
for a TextureView. It can currently be done with a bit of
JNI code.
Change-Id: Iaa7953097ab5beb8437bcbbfa03b2df5b7f80cd7
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index ca1e7ae..e167336 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -20,6 +20,7 @@
#include "LayerCache.h"
#include "LayerRenderer.h"
+#include "Matrix.h"
#include "Properties.h"
#include "Rect.h"
@@ -165,6 +166,40 @@
// Layers management
///////////////////////////////////////////////////////////////////////////////
+Layer* LayerRenderer::createTextureLayer() {
+ LAYER_RENDERER_LOGD("Creating new texture layer");
+
+ Layer* layer = new Layer(0, 0);
+ layer->isCacheable = false;
+ layer->isTextureLayer = true;
+ layer->blend = true;
+ layer->empty = true;
+ layer->fbo = 0;
+ layer->colorFilter = NULL;
+ layer->fbo = 0;
+ layer->layer.set(0.0f, 0.0f, 0.0f, 0.0f);
+ layer->texCoords.set(0.0f, 1.0f, 0.0f, 1.0f);
+ layer->alpha = 255;
+ layer->mode = SkXfermode::kSrcOver_Mode;
+ layer->colorFilter = NULL;
+ layer->region.clear();
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenTextures(1, &layer->texture);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, layer->texture);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ return layer;
+}
+
Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) {
LAYER_RENDERER_LOGD("Creating new layer %dx%d", width, height);
@@ -244,6 +279,18 @@
return true;
}
+void LayerRenderer::updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
+ float* transform) {
+ if (layer) {
+ layer->width = width;
+ layer->height = height;
+ layer->layer.set(0.0f, 0.0f, width, height);
+ layer->region.set(width, height);
+ layer->regionRect.set(0.0f, 0.0f, width, height);
+ layer->texTransform.load(transform);
+ }
+}
+
void LayerRenderer::destroyLayer(Layer* layer) {
if (layer) {
LAYER_RENDERER_LOGD("Destroying layer, fbo = %d", layer->fbo);