Add an API to set the transform on a TextureView's surface texture.
Bug #5156689 Change-Id: I635a625885c9b832a60d44ece0de7613ceb84109
This commit is contained in:
@@ -22478,12 +22478,14 @@ package android.view {
|
||||
method public android.graphics.Bitmap getBitmap(android.graphics.Bitmap);
|
||||
method public android.graphics.SurfaceTexture getSurfaceTexture();
|
||||
method public android.view.TextureView.SurfaceTextureListener getSurfaceTextureListener();
|
||||
method public android.graphics.Matrix getTransform(android.graphics.Matrix);
|
||||
method public boolean isAvailable();
|
||||
method public android.graphics.Canvas lockCanvas();
|
||||
method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
|
||||
method protected final void onDraw(android.graphics.Canvas);
|
||||
method public void setOpaque(boolean);
|
||||
method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
|
||||
method public void setTransform(android.graphics.Matrix);
|
||||
method public void unlockCanvasAndPost(android.graphics.Canvas);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
|
||||
static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque,
|
||||
SurfaceTexture surface);
|
||||
static native void nSetTextureLayerTransform(int layerId, int matrix);
|
||||
static native void nDestroyLayer(int layerId);
|
||||
static native void nDestroyLayerDeferred(int layerId);
|
||||
static native boolean nCopyLayer(int layerId, int bitmap);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.view;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
|
||||
/**
|
||||
* An OpenGL ES 2.0 implementation of {@link HardwareLayer}. This
|
||||
@@ -87,4 +88,11 @@ class GLES20RenderLayer extends GLES20Layer {
|
||||
}
|
||||
return getCanvas();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignored
|
||||
*/
|
||||
@Override
|
||||
void setTransform(Matrix matrix) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.view;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.SurfaceTexture;
|
||||
|
||||
/**
|
||||
@@ -75,4 +76,9 @@ class GLES20TextureLayer extends GLES20Layer {
|
||||
super.update(width, height, isOpaque);
|
||||
GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, isOpaque, mSurface);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setTransform(Matrix matrix) {
|
||||
GLES20Canvas.nSetTextureLayerTransform(mLayer, matrix.native_instance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.view;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
|
||||
/**
|
||||
* A hardware layer can be used to render graphics operations into a hardware
|
||||
@@ -150,4 +151,11 @@ abstract class HardwareLayer {
|
||||
mHeight = height;
|
||||
mOpaque = isOpaque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an optional transform on this layer.
|
||||
*
|
||||
* @param matrix The transform to apply to the layer.
|
||||
*/
|
||||
abstract void setTransform(Matrix matrix);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package android.view;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
@@ -104,6 +105,9 @@ public class TextureView extends View {
|
||||
|
||||
private boolean mOpaque = true;
|
||||
|
||||
private final Matrix mMatrix = new Matrix();
|
||||
private boolean mMatrixChanged;
|
||||
|
||||
private final Object[] mLock = new Object[0];
|
||||
private boolean mUpdateLayer;
|
||||
|
||||
@@ -312,6 +316,11 @@ public class TextureView extends View {
|
||||
|
||||
applyUpdate();
|
||||
|
||||
if (mMatrixChanged) {
|
||||
mLayer.setTransform(mMatrix);
|
||||
mMatrixChanged = false;
|
||||
}
|
||||
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
@@ -357,6 +366,50 @@ public class TextureView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the transform to associate with this texture view.
|
||||
* The specified transform applies to the underlying surface
|
||||
* texture and does not affect the size or position of the view
|
||||
* itself, only of its content.</p>
|
||||
*
|
||||
* <p>Some transforms might prevent the content from drawing
|
||||
* all the pixels contained within this view's bounds. In such
|
||||
* situations, make sure this texture view is not marked opaque.</p>
|
||||
*
|
||||
* @param transform The transform to apply to the content of
|
||||
* this view.
|
||||
*
|
||||
* @see #getTransform(android.graphics.Matrix)
|
||||
* @see #isOpaque()
|
||||
* @see #setOpaque(boolean)
|
||||
*/
|
||||
public void setTransform(Matrix transform) {
|
||||
mMatrix.set(transform);
|
||||
mMatrixChanged = true;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transform associated with this texture view.
|
||||
*
|
||||
* @param transform The {@link Matrix} in which to copy the current
|
||||
* transform. Can be null.
|
||||
*
|
||||
* @return The specified matrix if not null or a new {@link Matrix}
|
||||
* instance otherwise.
|
||||
*
|
||||
* @see #setTransform(android.graphics.Matrix)
|
||||
*/
|
||||
public Matrix getTransform(Matrix transform) {
|
||||
if (transform == null) {
|
||||
transform = new Matrix();
|
||||
}
|
||||
|
||||
transform.set(mMatrix);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns a {@link android.graphics.Bitmap} representation of the content
|
||||
* of the associated surface texture. If the surface texture is not available,
|
||||
|
||||
@@ -683,6 +683,12 @@ static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject cl
|
||||
LayerRenderer::updateTextureLayer(layer, width, height, isOpaque, renderTarget, transform);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_setTextureLayerTransform(JNIEnv* env, jobject clazz,
|
||||
Layer* layer, SkMatrix* matrix) {
|
||||
|
||||
layer->getTransform().load(*matrix);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env, jobject clazz, Layer* layer) {
|
||||
LayerRenderer::destroyLayer(layer);
|
||||
}
|
||||
@@ -827,6 +833,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nCreateTextureLayer", "(Z[I)I", (void*) android_view_GLES20Canvas_createTextureLayer },
|
||||
{ "nUpdateTextureLayer", "(IIIZLandroid/graphics/SurfaceTexture;)V",
|
||||
(void*) android_view_GLES20Canvas_updateTextureLayer },
|
||||
{ "nSetTextureLayerTransform", "(II)V", (void*) android_view_GLES20Canvas_setTextureLayerTransform },
|
||||
{ "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer },
|
||||
{ "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred },
|
||||
{ "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer },
|
||||
|
||||
@@ -203,6 +203,10 @@ struct Layer {
|
||||
return texTransform;
|
||||
}
|
||||
|
||||
inline mat4& getTransform() {
|
||||
return transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bounds of the layer.
|
||||
*/
|
||||
@@ -282,6 +286,11 @@ private:
|
||||
*/
|
||||
mat4 texTransform;
|
||||
|
||||
/**
|
||||
* Optional transform.
|
||||
*/
|
||||
mat4 transform;
|
||||
|
||||
}; // struct Layer
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
@@ -51,6 +51,7 @@ void Matrix4::loadIdentity() {
|
||||
data[kTranslateZ] = 0.0f;
|
||||
data[kPerspective2] = 1.0f;
|
||||
|
||||
mIsIdentity = true;
|
||||
mSimpleMatrix = true;
|
||||
}
|
||||
|
||||
@@ -71,14 +72,21 @@ bool Matrix4::isSimple() {
|
||||
return mSimpleMatrix;
|
||||
}
|
||||
|
||||
bool Matrix4::isIdentity() {
|
||||
return mIsIdentity;
|
||||
}
|
||||
|
||||
void Matrix4::load(const float* v) {
|
||||
memcpy(data, v, sizeof(data));
|
||||
// TODO: Do something smarter here
|
||||
mSimpleMatrix = false;
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::load(const Matrix4& v) {
|
||||
memcpy(data, v.data, sizeof(data));
|
||||
mSimpleMatrix = v.mSimpleMatrix;
|
||||
mIsIdentity = v.mIsIdentity;
|
||||
}
|
||||
|
||||
void Matrix4::load(const SkMatrix& v) {
|
||||
@@ -99,6 +107,7 @@ void Matrix4::load(const SkMatrix& v) {
|
||||
data[kScaleZ] = 1.0f;
|
||||
|
||||
mSimpleMatrix = (v.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask));
|
||||
mIsIdentity = v.isIdentity();
|
||||
}
|
||||
|
||||
void Matrix4::copyTo(SkMatrix& v) const {
|
||||
@@ -148,6 +157,7 @@ void Matrix4::loadInverse(const Matrix4& v) {
|
||||
v.data[kSkewX] * v.data[kSkewY]) * scale;
|
||||
|
||||
mSimpleMatrix = v.mSimpleMatrix;
|
||||
mIsIdentity = v.mIsIdentity;
|
||||
}
|
||||
|
||||
void Matrix4::copyTo(float* v) const {
|
||||
@@ -166,20 +176,27 @@ void Matrix4::multiply(float v) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
data[i] *= v;
|
||||
}
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::loadTranslate(float x, float y, float z) {
|
||||
loadIdentity();
|
||||
|
||||
data[kTranslateX] = x;
|
||||
data[kTranslateY] = y;
|
||||
data[kTranslateZ] = z;
|
||||
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::loadScale(float sx, float sy, float sz) {
|
||||
loadIdentity();
|
||||
|
||||
data[kScaleX] = sx;
|
||||
data[kScaleY] = sy;
|
||||
data[kScaleZ] = sz;
|
||||
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::loadSkew(float sx, float sy) {
|
||||
@@ -198,6 +215,7 @@ void Matrix4::loadSkew(float sx, float sy) {
|
||||
data[kPerspective2] = 1.0f;
|
||||
|
||||
mSimpleMatrix = false;
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::loadRotate(float angle, float x, float y, float z) {
|
||||
@@ -238,6 +256,7 @@ void Matrix4::loadRotate(float angle, float x, float y, float z) {
|
||||
data[kScaleZ] = z * z * nc + c;
|
||||
|
||||
mSimpleMatrix = false;
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {
|
||||
@@ -262,16 +281,20 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {
|
||||
}
|
||||
|
||||
mSimpleMatrix = u.mSimpleMatrix && v.mSimpleMatrix;
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
|
||||
loadIdentity();
|
||||
|
||||
data[kScaleX] = 2.0f / (right - left);
|
||||
data[kScaleY] = 2.0f / (top - bottom);
|
||||
data[kScaleZ] = -2.0f / (far - near);
|
||||
data[kTranslateX] = -(right + left) / (right - left);
|
||||
data[kTranslateY] = -(top + bottom) / (top - bottom);
|
||||
data[kTranslateZ] = -(far + near) / (far - near);
|
||||
|
||||
mIsIdentity = false;
|
||||
}
|
||||
|
||||
#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)
|
||||
|
||||
@@ -112,6 +112,7 @@ public:
|
||||
|
||||
bool isPureTranslate();
|
||||
bool isSimple();
|
||||
bool isIdentity();
|
||||
|
||||
bool changesBounds();
|
||||
|
||||
@@ -128,6 +129,7 @@ public:
|
||||
|
||||
private:
|
||||
bool mSimpleMatrix;
|
||||
bool mIsIdentity;
|
||||
|
||||
inline float get(int i, int j) const {
|
||||
return data[i * 4 + j];
|
||||
|
||||
@@ -627,6 +627,12 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
|
||||
float alpha = layer->getAlpha() / 255.0f;
|
||||
|
||||
mat4& transform = layer->getTransform();
|
||||
if (!transform.isIdentity()) {
|
||||
save(0);
|
||||
mSnapshot->transform->multiply(transform);
|
||||
}
|
||||
|
||||
setupDraw();
|
||||
if (layer->getRenderTarget() == GL_TEXTURE_2D) {
|
||||
setupDrawWithTexture();
|
||||
@@ -663,6 +669,10 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
|
||||
|
||||
finishDrawTexture();
|
||||
|
||||
if (!transform.isIdentity()) {
|
||||
restore();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.test.hwui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Bundle;
|
||||
@@ -33,6 +34,7 @@ public class TextureViewActivity extends Activity implements TextureView.Surface
|
||||
private Camera mCamera;
|
||||
private TextureView mTextureView;
|
||||
private FrameLayout mContent;
|
||||
private Matrix mMatrix = new Matrix();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -82,8 +84,6 @@ public class TextureViewActivity extends Activity implements TextureView.Surface
|
||||
}
|
||||
|
||||
mCamera.startPreview();
|
||||
|
||||
mTextureView.setCameraDistance(5000);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user