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);