Skip to content

Commit a9dc86b

Browse files
author
Romain Guy
committed
Correctly apply transforms when getting a TextureView's bitmap
Bug #5439406 Change-Id: I271a9a2e38f5b3600dc158f8f442a6b0893f472b
1 parent 098ffcd commit a9dc86b

File tree

3 files changed

+81
-9
lines changed

3 files changed

+81
-9
lines changed

libs/hwui/LayerRenderer.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ Layer* LayerRenderer::createTextureLayer(bool isOpaque) {
264264
layer->setFbo(0);
265265
layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
266266
layer->layer.set(0.0f, 0.0f, 0.0f, 0.0f);
267-
layer->texCoords.set(0.0f, 1.0f, 0.0f, 1.0f);
267+
layer->texCoords.set(0.0f, 1.0f, 1.0f, 0.0f);
268268
layer->region.clear();
269269
layer->setRenderTarget(GL_NONE); // see ::updateTextureLayer()
270270

@@ -400,6 +400,18 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
400400
renderer.setViewport(bitmap->width(), bitmap->height());
401401
renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f,
402402
bitmap->width(), bitmap->height(), !layer->isBlend());
403+
404+
glDisable(GL_SCISSOR_TEST);
405+
renderer.translate(0.0f, bitmap->height());
406+
renderer.scale(1.0f, -1.0f);
407+
408+
mat4 texTransform(layer->getTexTransform());
409+
410+
mat4 invert;
411+
invert.translate(0.0f, 1.0f, 0.0f);
412+
invert.scale(1.0f, -1.0f, 1.0f);
413+
layer->getTexTransform().multiply(invert);
414+
403415
if ((error = glGetError()) != GL_NO_ERROR) goto error;
404416

405417
{
@@ -413,6 +425,7 @@ bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
413425
if ((error = glGetError()) != GL_NO_ERROR) goto error;
414426
}
415427

428+
layer->getTexTransform().load(texTransform);
416429
status = true;
417430
}
418431

tests/HwAccelerationTest/src/com/android/test/hwui/GLTextureViewActivity.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@
2222
import android.content.res.Resources;
2323
import android.graphics.Bitmap;
2424
import android.graphics.BitmapFactory;
25+
import android.graphics.Matrix;
2526
import android.graphics.SurfaceTexture;
2627
import android.opengl.GLUtils;
2728
import android.os.Bundle;
29+
import android.os.Environment;
2830
import android.util.Log;
2931
import android.view.Gravity;
3032
import android.view.TextureView;
@@ -39,6 +41,7 @@
3941
import javax.microedition.khronos.egl.EGLSurface;
4042
import javax.microedition.khronos.opengles.GL;
4143
import java.io.BufferedOutputStream;
44+
import java.io.File;
4245
import java.io.FileNotFoundException;
4346
import java.io.FileOutputStream;
4447
import java.io.IOException;
@@ -65,7 +68,8 @@ public void onClick(View v) {
6568
Bitmap b = mTextureView.getBitmap(800, 800);
6669
BufferedOutputStream out = null;
6770
try {
68-
out = new BufferedOutputStream(new FileOutputStream("/sdcard/out.png"));
71+
File dump = new File(Environment.getExternalStorageDirectory(), "out.png");
72+
out = new BufferedOutputStream(new FileOutputStream(dump));
6973
b.compress(Bitmap.CompressFormat.PNG, 100, out);
7074
} catch (FileNotFoundException e) {
7175
e.printStackTrace();
@@ -168,10 +172,10 @@ private static class RenderThread extends Thread {
168172
private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
169173
private final float[] mTriangleVerticesData = {
170174
// X, Y, Z, U, V
171-
-1.0f, -1.0f, 0, 0.f, 0.f,
172-
1.0f, -1.0f, 0, 1.f, 0.f,
173-
-1.0f, 1.0f, 0, 0.f, 1.f,
174-
1.0f, 1.0f, 0, 1.f, 1.f,
175+
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
176+
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
177+
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
178+
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
175179
};
176180

177181
@Override
@@ -212,8 +216,6 @@ public void run() {
212216
while (!mFinished) {
213217
checkCurrent();
214218

215-
Log.d(LOG_TAG, "Rendering frame");
216-
217219
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
218220
checkGlError();
219221

@@ -237,7 +239,7 @@ public void run() {
237239
checkEglError();
238240

239241
try {
240-
Thread.sleep(20);
242+
Thread.sleep(2000);
241243
} catch (InterruptedException e) {
242244
// Ignore
243245
}

tests/HwAccelerationTest/src/com/android/test/hwui/TextureViewActivity.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,23 @@
1717
package com.android.test.hwui;
1818

1919
import android.app.Activity;
20+
import android.graphics.Bitmap;
2021
import android.graphics.Matrix;
2122
import android.graphics.SurfaceTexture;
2223
import android.hardware.Camera;
2324
import android.os.Bundle;
25+
import android.os.Environment;
2426
import android.view.Gravity;
27+
import android.view.Surface;
2528
import android.view.TextureView;
2629
import android.view.View;
2730
import android.widget.Button;
2831
import android.widget.FrameLayout;
2932

33+
import java.io.BufferedOutputStream;
34+
import java.io.File;
35+
import java.io.FileNotFoundException;
36+
import java.io.FileOutputStream;
3037
import java.io.IOException;
3138

3239
@SuppressWarnings({"UnusedDeclaration"})
@@ -44,6 +51,26 @@ protected void onCreate(Bundle savedInstanceState) {
4451

4552
mTextureView = new TextureView(this);
4653
mTextureView.setSurfaceTextureListener(this);
54+
mTextureView.setOnClickListener(new View.OnClickListener() {
55+
@Override
56+
public void onClick(View v) {
57+
Bitmap b = mTextureView.getBitmap(800, 800);
58+
BufferedOutputStream out = null;
59+
try {
60+
File dump = new File(Environment.getExternalStorageDirectory(), "out.png");
61+
out = new BufferedOutputStream(new FileOutputStream(dump));
62+
b.compress(Bitmap.CompressFormat.PNG, 100, out);
63+
} catch (FileNotFoundException e) {
64+
e.printStackTrace();
65+
} finally {
66+
if (out != null) try {
67+
out.close();
68+
} catch (IOException e) {
69+
e.printStackTrace();
70+
}
71+
}
72+
}
73+
});
4774

4875
Button button = new Button(this);
4976
button.setText("Remove/Add");
@@ -73,6 +100,8 @@ public void onClick(View v) {
73100
@Override
74101
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
75102
mCamera = Camera.open();
103+
mCamera.setDisplayOrientation(getCameraOrientation());
104+
76105
Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
77106
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(
78107
previewSize.width, previewSize.height, Gravity.CENTER));
@@ -86,6 +115,34 @@ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int hei
86115
mCamera.startPreview();
87116
}
88117

118+
private int getCameraOrientation() {
119+
Camera.CameraInfo info = new Camera.CameraInfo();
120+
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
121+
Camera.getCameraInfo(i, info);
122+
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) break;
123+
}
124+
125+
int rotation = getWindowManager().getDefaultDisplay().getRotation();
126+
int degrees = 0;
127+
128+
switch (rotation) {
129+
case Surface.ROTATION_0:
130+
degrees = 0;
131+
break;
132+
case Surface.ROTATION_90:
133+
degrees = 90;
134+
break;
135+
case Surface.ROTATION_180:
136+
degrees = 180;
137+
break;
138+
case Surface.ROTATION_270:
139+
degrees = 270;
140+
break;
141+
}
142+
143+
return (info.orientation - degrees + 360) % 360;
144+
}
145+
89146
@Override
90147
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
91148
// Ignored, the Camera does all the work for us

0 commit comments

Comments
 (0)