diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java | 49 | ||||
-rw-r--r-- | core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp | 9 |
2 files changed, 34 insertions, 24 deletions
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java index 3f24b2c..b1b0f9b 100644 --- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java +++ b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java @@ -16,6 +16,7 @@ package android.hardware.camera2.legacy; import android.graphics.ImageFormat; +import android.graphics.RectF; import android.graphics.SurfaceTexture; import android.os.Environment; import android.opengl.EGL14; @@ -194,6 +195,9 @@ public class SurfaceTextureRenderer { checkGlError("onDrawFrame start"); st.getTransformMatrix(mSTMatrix); + Matrix.setIdentityM(mMVPMatrix, /*smOffset*/0); + + // Find intermediate buffer dimensions Size dimens; try { dimens = LegacyCameraDevice.getTextureSize(st); @@ -201,9 +205,6 @@ public class SurfaceTextureRenderer { // Should never hit this. throw new IllegalStateException("Surface abandoned, skipping drawFrame...", e); } - - Matrix.setIdentityM(mMVPMatrix, /*smOffset*/0); - float texWidth = dimens.getWidth(); float texHeight = dimens.getHeight(); @@ -211,32 +212,30 @@ public class SurfaceTextureRenderer { throw new IllegalStateException("Illegal intermediate texture with dimension of 0"); } - // Find largest scaling factor from the intermediate texture dimension to the - // output surface dimension. Scaling the intermediate texture by this allows - // us to letterbox/pillerbox the output surface into the intermediate texture. - float widthRatio = width / texWidth; - float heightRatio = height / texHeight; - float actual = (widthRatio < heightRatio) ? heightRatio : widthRatio; + // Letterbox or pillerbox output dimensions into intermediate dimensions. + RectF intermediate = new RectF(/*left*/0, /*top*/0, /*right*/texWidth, /*bottom*/texHeight); + RectF output = new RectF(/*left*/0, /*top*/0, /*right*/width, /*bottom*/height); + android.graphics.Matrix boxingXform = new android.graphics.Matrix(); + boxingXform.setRectToRect(output, intermediate, android.graphics.Matrix.ScaleToFit.CENTER); + boxingXform.mapRect(output); - if (DEBUG) { - Log.d(TAG, "Scaling factor " + actual + " used for " + width + "x" + height + - " surface, intermediate buffer size is " + texWidth + "x" + texHeight); - } + // Find scaling factor from pillerboxed/letterboxed output dimensions to intermediate + // buffer dimensions. + float scaleX = intermediate.width() / output.width(); + float scaleY = intermediate.height() / output.height(); - // Set the viewport height and width to be the scaled intermediate texture dimensions. - int viewportW = (int) (actual * texWidth); - int viewportH = (int) (actual * texHeight); - - // Set the offset of the viewport so that the output surface is centered in the viewport. - float dx = (width - viewportW) / 2f; - float dy = (height - viewportH) / 2f; + // Scale opposite dimension in clip coordinates so output is letterboxed/pillerboxed into + // the intermediate dimensions (rather than vice-versa). + Matrix.scaleM(mMVPMatrix, /*offset*/0, /*x*/scaleY, /*y*/scaleX, /*z*/1); if (DEBUG) { - Log.d(TAG, "Translation " + dx + "," + dy + " used for " + width + "x" + height + - " surface"); + Log.d(TAG, "Scaling factors (S_x = " + scaleX + ",S_y = " + scaleY + ") used for " + + width + "x" + height + " surface, intermediate buffer size is " + texWidth + + "x" + texHeight); } - GLES20.glViewport((int) dx, (int) dy, viewportW, viewportH); + // Set viewport to be output buffer dimensions + GLES20.glViewport(0, 0, width, height); if (DEBUG) { GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f); @@ -251,7 +250,7 @@ public class SurfaceTextureRenderer { mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); GLES20.glVertexAttribPointer(maPositionHandle, VERTEX_POS_SIZE, GLES20.GL_FLOAT, - /*normalized*/ false,TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); + /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); checkGlError("glVertexAttribPointer maPosition"); GLES20.glEnableVertexAttribArray(maPositionHandle); checkGlError("glEnableVertexAttribArray maPositionHandle"); @@ -654,6 +653,8 @@ public class SurfaceTextureRenderer { if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) { makeCurrent(holder.eglSurface); try { + LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width, + holder.height); LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second); drawFrame(mSurfaceTexture, holder.width, holder.height); swapBuffers(holder.eglSurface); diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp index 697cdc6..4cc36aa 100644 --- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp +++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp @@ -541,6 +541,15 @@ static jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, ALOGE("%s: Error while setting surface dimens %s (%d).", __FUNCTION__, strerror(-err), err); return err; } + + // WAR - Set user dimensions also to avoid incorrect scaling after TextureView orientation + // change. + err = native_window_set_buffers_user_dimensions(anw.get(), width, height); + if (err != NO_ERROR) { + ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err), + err); + return err; + } return NO_ERROR; } |