diff options
25 files changed, 396 insertions, 186 deletions
diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp index b9938eb6b..8d0632402 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/Renderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/Renderer.cpp @@ -111,8 +111,8 @@ GLuint Renderer::createProgram(const char* pVertexSource, const char* pFragmentS } // Set this renderer to use the default frame-buffer (screen) and -// set the viewport size to be the given width and height (pixels). -bool Renderer::SetupGraphics(int width, int height) +// set the viewport size to be the given x, y, width and height (pixels). +bool Renderer::SetupGraphics(int x, int y, int width, int height) { bool succeeded = false; do { @@ -131,8 +131,10 @@ bool Renderer::SetupGraphics(int width, int height) mFrameBuffer = NULL; mSurfaceWidth = width; mSurfaceHeight = height; + mSurfaceXOffset = x; + mSurfaceYOffset = y; - glViewport(0, 0, mSurfaceWidth, mSurfaceHeight); + glViewport(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight); if (!checkGlError("glViewport")) break; succeeded = true; } while (false); @@ -176,7 +178,7 @@ bool Renderer::Clear(float r, float g, float b, float a) bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/feature_mos/src/mosaic_renderer/Renderer.h b/jni/feature_mos/src/mosaic_renderer/Renderer.h index a43e8028e..ffb9cbd25 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/Renderer.h +++ b/jni/feature_mos/src/mosaic_renderer/Renderer.h @@ -18,7 +18,7 @@ class Renderer { virtual bool InitializeGLProgram() = 0; bool SetupGraphics(FrameBuffer* buffer); - bool SetupGraphics(int width, int height); + bool SetupGraphics(int x, int y, int width, int height); bool Clear(float r, float g, float b, float a); @@ -59,6 +59,8 @@ class Renderer { int mSurfaceWidth; // Width of target surface. int mSurfaceHeight; // Height of target surface. + int mSurfaceXOffset; // X Offset target surface. + int mSurfaceYOffset; // Y Offset of target surface. FrameBuffer *mFrameBuffer; }; diff --git a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp index 88aac3626..4725463f2 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/SurfaceTextureRenderer.cpp @@ -119,7 +119,7 @@ bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine) bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp index af6779a3f..e4755b1ed 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.cpp @@ -68,6 +68,51 @@ void WarpRenderer::SetScalingMatrix(float xscale, float yscale) mScalingMatrix[15] = 1.0f; } +void WarpRenderer::SetRotation(int degree) +{ + for(int i=0; i<16; i++) + { + mRotationMatrix[i] = 0.0f; + } + + switch(degree) + { + case 0: + mRotationMatrix[0] = 1.0f; + mRotationMatrix[1] = 0.0f; + mRotationMatrix[4] = 0.0f; + mRotationMatrix[5] = 1.0f; + break; + case 90: + mRotationMatrix[0] = 0.0f; + mRotationMatrix[1] = 1.0f; + mRotationMatrix[4] = -1.0f; + mRotationMatrix[5] = 0.0f; + break; + case 180: + mRotationMatrix[0] = -1.0f; + mRotationMatrix[1] = 0.0f; + mRotationMatrix[4] = 0.0f; + mRotationMatrix[5] = -1.0f; + break; + case 270: + mRotationMatrix[0] = 0.0f; + mRotationMatrix[1] = -1.0f; + mRotationMatrix[4] = 1.0f; + mRotationMatrix[5] = 0.0f; + break; + default: + mRotationMatrix[0] = 1.0f; + mRotationMatrix[1] = 0.0f; + mRotationMatrix[4] = 0.0f; + mRotationMatrix[5] = 1.0f; + break; + } + + mRotationMatrix[10] = 1.0f; + mRotationMatrix[15] = 1.0f; +} + bool WarpRenderer::InitializeGLProgram() { bool succeeded = false; @@ -87,6 +132,7 @@ bool WarpRenderer::InitializeGLProgram() mAffinetransLoc = glGetUniformLocation(glProgram, "u_affinetrans"); mViewporttransLoc = glGetUniformLocation(glProgram, "u_viewporttrans"); mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans"); + mRotationtransLoc = glGetUniformLocation(glProgram, "u_rotationtrans"); mTexCoordLoc = glGetAttribLocation(glProgram, "a_texCoord"); // Get sampler location @@ -110,7 +156,7 @@ bool WarpRenderer::DrawTexture(GLfloat *affine) bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) @@ -143,6 +189,7 @@ bool WarpRenderer::DrawTexture(GLfloat *affine) glUniformMatrix4fv(mAffinetransLoc, 1, GL_FALSE, affine); glUniformMatrix4fv(mViewporttransLoc, 1, GL_FALSE, mViewportMatrix); glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix); + glUniformMatrix4fv(mRotationtransLoc, 1, GL_FALSE, mRotationMatrix); // And, finally, execute the GL draw command. glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices); @@ -161,12 +208,13 @@ const char* WarpRenderer::VertexShaderSource() const "uniform mat4 u_affinetrans; \n" "uniform mat4 u_viewporttrans; \n" "uniform mat4 u_scalingtrans; \n" + "uniform mat4 u_rotationtrans; \n" "attribute vec4 a_position; \n" "attribute vec2 a_texCoord; \n" "varying vec2 v_texCoord; \n" "void main() \n" "{ \n" - " gl_Position = u_scalingtrans * u_viewporttrans * u_affinetrans * a_position; \n" + " gl_Position = u_scalingtrans * u_viewporttrans * u_affinetrans * u_rotationtrans * a_position; \n" " v_texCoord = a_texCoord; \n" "} \n"; diff --git a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.h b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.h index 8e9a694ec..2f50c6f34 100755 --- a/jni/feature_mos/src/mosaic_renderer/WarpRenderer.h +++ b/jni/feature_mos/src/mosaic_renderer/WarpRenderer.h @@ -20,7 +20,7 @@ class WarpRenderer: public Renderer { void SetViewportMatrix(int w, int h, int W, int H); void SetScalingMatrix(float xscale, float yscale); - + void SetRotation(int degree); bool DrawTexture(GLfloat *affine); private: @@ -38,9 +38,11 @@ class WarpRenderer: public Renderer { GLint mViewporttransLoc; GLint mScalingtransLoc; GLint mTexCoordLoc; + GLint mRotationtransLoc; GLfloat mViewportMatrix[16]; GLfloat mScalingMatrix[16]; + GLfloat mRotationMatrix[16]; // Sampler location GLint mSamplerLoc; diff --git a/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp b/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp index f7dcf6f61..b30e6f7b6 100755..100644 --- a/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp +++ b/jni/feature_mos/src/mosaic_renderer/YVURenderer.cpp @@ -79,7 +79,7 @@ bool YVURenderer::DrawTexture() bool succeeded = false; do { bool rt = (mFrameBuffer == NULL)? - SetupGraphics(mSurfaceWidth, mSurfaceHeight) : + SetupGraphics(mSurfaceXOffset, mSurfaceYOffset, mSurfaceWidth, mSurfaceHeight) : SetupGraphics(mFrameBuffer); if(!rt) diff --git a/jni/mosaic_renderer_jni.cpp b/jni/mosaic_renderer_jni.cpp index 36f8064c7..6c52b542e 100644 --- a/jni/mosaic_renderer_jni.cpp +++ b/jni/mosaic_renderer_jni.cpp @@ -36,6 +36,8 @@ GLuint gSurfaceTextureID[1]; bool gWarpImage = true; +bool gPreviewBackgroundImage = true; +bool gEnableWarpedPanoPreview = false; // Low-Res input image frame in YUVA format for preview rendering and processing // and high-res YUVA input image for processing. @@ -87,6 +89,9 @@ FrameBuffer gBuffer[2]; // Shader to warp and render the preview FBO to the screen WarpRenderer gPreview; +// Shader to render the fullscreen preview background FBO to the screen +WarpRenderer gPreviewBackground; + // Index of the gBuffer FBO gWarper1 is going to write into int gCurrentFBOIndex = 0; @@ -122,6 +127,9 @@ double gUILayoutScalingY = 1.0f; // orientation. bool gIsLandscapeOrientation = true; +// Current device orientation +int gOrientation = 0; + // State of the viewfinder. Set to false when the viewfinder hits the UI edge. bool gPanViewfinder = true; @@ -315,8 +323,8 @@ void UpdateWarpTransformation(float *trs) // Alignment is done based on low-res data. // To render the preview mosaic, the translation of the high-res mosaic is estimated to // H2L_FACTOR x low-res-based tranlation. - gThisH1t[2] *= H2L_FACTOR; - gThisH1t[5] *= H2L_FACTOR; + //gThisH1t[2] *= H2L_FACTOR; + //gThisH1t[5] *= H2L_FACTOR; db_Identity3x3(T); T[2] = -gCenterOffsetX; @@ -397,13 +405,13 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) gPreviewImageHeight[HR], 4); sem_post(&gPreviewImage_semaphore); - gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[HR]; - gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[HR]; + gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]; + gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]; // The origin is such that the current frame will sit with its center // at the center of the previewFBO - gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[HR] / 2); - gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[HR] / 2); + gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[LR] / 2); + gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[LR] / 2); gPanOffset = 0.0f; @@ -412,8 +420,8 @@ void AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) gPanViewfinder = true; - int w = gPreviewImageWidth[HR]; - int h = gPreviewImageHeight[HR]; + int w = gPreviewImageWidth[LR]; + int h = gPreviewImageHeight[LR]; int wm = gPreviewFBOWidth; int hm = gPreviewFBOHeight; @@ -479,10 +487,10 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved); JNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( - JNIEnv * env, jobject obj); + JNIEnv * env, jobject obj, jboolean mEnableWarpedPanoPreview); JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( JNIEnv * env, jobject obj, jint width, jint height, - jboolean isLandscapeOrientation); + jboolean isLandscapeOrientation, jint orientation); JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( JNIEnv * env, jobject obj, jfloatArray stMatrix); JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_transferGPUtoCPU( @@ -493,6 +501,8 @@ extern "C" JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( JNIEnv * env, jobject obj, jboolean flag); + JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setPreviewBackground( + JNIEnv * env, jobject obj, jboolean flag); }; @@ -509,21 +519,25 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) sem_destroy(&gPreviewImage_semaphore); } JNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( - JNIEnv * env, jobject obj) + JNIEnv * env, jobject obj, jboolean mEnableWarpedPanoPreview) { + gEnableWarpedPanoPreview = mEnableWarpedPanoPreview; gSurfTexRenderer[LR].InitializeGLProgram(); gSurfTexRenderer[HR].InitializeGLProgram(); gYVURenderer[LR].InitializeGLProgram(); gYVURenderer[HR].InitializeGLProgram(); - gWarper1.InitializeGLProgram(); - gWarper2.InitializeGLProgram(); - gPreview.InitializeGLProgram(); - gBuffer[0].InitializeGLContext(); - gBuffer[1].InitializeGLContext(); + if (gEnableWarpedPanoPreview) { + gWarper1.InitializeGLProgram(); + gWarper2.InitializeGLProgram(); + gPreview.InitializeGLProgram(); + gBuffer[0].InitializeGLContext(); + gBuffer[1].InitializeGLContext(); + } gBufferInput[LR].InitializeGLContext(); gBufferInput[HR].InitializeGLContext(); gBufferInputYVU[LR].InitializeGLContext(); gBufferInputYVU[HR].InitializeGLContext(); + gPreviewBackground.InitializeGLProgram(); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -579,13 +593,17 @@ void calculateUILayoutScaling(int width, int height, bool isLandscape) { } JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( - JNIEnv * env, jobject obj, jint width, jint height, jboolean isLandscapeOrientation) + JNIEnv * env, jobject obj, jint width, jint height, + jboolean isLandscapeOrientation, jint orientation) { gIsLandscapeOrientation = isLandscapeOrientation; - calculateUILayoutScaling(width, height, gIsLandscapeOrientation); + gOrientation = orientation; + calculateUILayoutScaling(gPreviewFBOWidth, gPreviewFBOHeight, gIsLandscapeOrientation); - gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); - gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); + if (gEnableWarpedPanoPreview) { + gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); + gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); + } gBufferInput[LR].Init(gPreviewImageWidth[LR], gPreviewImageHeight[LR], GL_RGBA); @@ -626,37 +644,76 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( gYVURenderer[HR].SetInputTextureName(gBufferInput[HR].GetTextureName()); gYVURenderer[HR].SetInputTextureType(GL_TEXTURE_2D); - // gBuffer[1-gCurrentFBOIndex] --> gWarper1 --> gBuffer[gCurrentFBOIndex] - gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - - // Clear the destination buffer of gWarper1. - gWarper1.Clear(0.0, 0.0, 0.0, 1.0); - gWarper1.SetViewportMatrix(1, 1, 1, 1); - gWarper1.SetScalingMatrix(1.0f, 1.0f); - gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName()); - gWarper1.SetInputTextureType(GL_TEXTURE_2D); - - // gBufferInput[HR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] - gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - - // gWarp2's destination buffer is the same to gWarp1's. No need to clear it - // again. - gWarper2.SetViewportMatrix(gPreviewImageWidth[HR], - gPreviewImageHeight[HR], gBuffer[gCurrentFBOIndex].GetWidth(), - gBuffer[gCurrentFBOIndex].GetHeight()); - gWarper2.SetScalingMatrix(1.0f, 1.0f); - gWarper2.SetInputTextureName(gBufferInput[HR].GetTextureName()); - gWarper2.SetInputTextureType(GL_TEXTURE_2D); - - // gBuffer[gCurrentFBOIndex] --> gPreview --> Screen - gPreview.SetupGraphics(width, height); - gPreview.SetViewportMatrix(1, 1, 1, 1); - - // Scale the previewFBO so that the viewfinder window fills the layout height - // while maintaining the image aspect ratio - gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY); - gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - gPreview.SetInputTextureType(GL_TEXTURE_2D); + if(gEnableWarpedPanoPreview) { + // gBuffer[1-gCurrentFBOIndex] --> gWarper1 --> gBuffer[gCurrentFBOIndex] + gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); + + // Clear the destination buffer of gWarper1. + gWarper1.Clear(0.0, 0.0, 0.0, 1.0); + gWarper1.SetViewportMatrix(1, 1, 1, 1); + gWarper1.SetScalingMatrix(1.0f, 1.0f); + gWarper1.SetRotation(0); + gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName()); + gWarper1.SetInputTextureType(GL_TEXTURE_2D); + + // gBufferInput[LR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] + gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); + + // gWarp2's destination buffer is the same to gWarp1's. No need to clear it + // again. + gWarper2.SetViewportMatrix(gPreviewImageWidth[LR], + gPreviewImageHeight[LR], gBuffer[gCurrentFBOIndex].GetWidth(), + gBuffer[gCurrentFBOIndex].GetHeight()); + gWarper2.SetScalingMatrix(1.0f, 1.0f); + gWarper2.SetRotation(0); + gWarper2.SetInputTextureName(gBufferInput[LR].GetTextureName()); + gWarper2.SetInputTextureType(GL_TEXTURE_2D); + + int xoffset = (width / 2 - gPreviewFBOWidth / 2); + int yoffset = (height / 2 - gPreviewFBOHeight / 2); + if (gOrientation == 0) { + yoffset = (height - gPreviewFBOHeight) * 1 / 5; + } else { + yoffset = (height - gPreviewFBOHeight) * 4 / 5; + } + + // gBuffer[gCurrentFBOIndex] --> gPreview --> Screen + if(!gIsLandscapeOrientation) { + gPreview.SetupGraphics(xoffset,yoffset,gPreviewFBOWidth, gPreviewFBOHeight); + } else { + yoffset = (height / 2 - gPreviewFBOWidth / 2); + if (gOrientation == 90) { + xoffset = (width - gPreviewFBOHeight) * 4 / 5; + } else { + xoffset = (width - gPreviewFBOHeight) * 1 / 5; + } + gPreview.SetupGraphics(xoffset,yoffset,gPreviewFBOHeight ,gPreviewFBOWidth); + } + gPreview.SetViewportMatrix(1, 1, 1, 1); + + // Scale the previewFBO so that the viewfinder window fills the layout height + // while maintaining the image aspect ratio + gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY); + gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); + gPreview.SetInputTextureType(GL_TEXTURE_2D); + if (gIsLandscapeOrientation) { + gPreview.SetRotation(90); + } else { + gPreview.SetRotation(0); + } + } + + // gBufferInput[HR] --> gPreviewBackground --> screen + gPreviewBackground.SetupGraphics(0,0,width, height); + gPreviewBackground.SetViewportMatrix(1,1,1,1); + gPreviewBackground.SetScalingMatrix(1.0f, -1.0f); + gPreviewBackground.SetInputTextureName(gBufferInput[HR].GetTextureName()); + gPreviewBackground.SetInputTextureType(GL_TEXTURE_2D); + if (gIsLandscapeOrientation) { + gPreviewBackground.SetRotation(90); + } else { + gPreviewBackground.SetRotation(0); + } } JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( @@ -731,32 +788,37 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step( { if(!gWarpImage) // ViewFinder { - gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - - gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); - if (gIsLandscapeOrientation) { - gPreview.DrawTexture(g_dAffinetransIdentGL); + gPreviewBackground.DrawTexture(g_dAffinetransIdentGL); } else { - gPreview.DrawTexture(g_dAffinetransRotation90GL); + gPreviewBackground.DrawTexture(g_dAffinetransRotation90GL); + } + } + else if (gPreviewBackgroundImage) + { + if (gIsLandscapeOrientation) { + gPreviewBackground.DrawTexture(g_dAffinetransIdentGL); + } else { + gPreviewBackground.DrawTexture(g_dAffinetransRotation90GL); } } else { - gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - // Clear the destination so that we can paint on it afresh - gWarper1.Clear(0.0, 0.0, 0.0, 1.0); - gWarper1.SetInputTextureName( - gBuffer[1 - gCurrentFBOIndex].GetTextureName()); - gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); - gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); - - gWarper1.DrawTexture(g_dAffinetransGL); - gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); - gPreview.DrawTexture(g_dAffinetransPanGL); - - gCurrentFBOIndex = 1 - gCurrentFBOIndex; + if (gEnableWarpedPanoPreview) { + gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); + // Clear the destination so that we can paint on it afresh + gWarper1.Clear(0.0, 0.0, 0.0, 1.0); + gWarper1.SetInputTextureName( + gBuffer[1 - gCurrentFBOIndex].GetTextureName()); + gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); + gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); + + gWarper1.DrawTexture(g_dAffinetransGL); + gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); + gPreview.DrawTexture(g_dAffinetransPanGL); + + gCurrentFBOIndex = 1 - gCurrentFBOIndex; + } } } @@ -766,15 +828,17 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( // TODO: Review this logic if(gWarpImage != (bool) flag) //switching from viewfinder to capture or vice-versa { - // Clear gBuffer[0] - gWarper1.SetupGraphics(&gBuffer[0]); - gWarper1.Clear(0.0, 0.0, 0.0, 1.0); - // Clear gBuffer[1] - gWarper1.SetupGraphics(&gBuffer[1]); - gWarper1.Clear(0.0, 0.0, 0.0, 1.0); - // Clear the screen to black. - gPreview.Clear(0.0, 0.0, 0.0, 1.0); - + if (gEnableWarpedPanoPreview) { + // Clear gBuffer[0] + gWarper1.SetupGraphics(&gBuffer[0]); + gWarper1.Clear(0.0, 0.0, 0.0, 1.0); + // Clear gBuffer[1] + gWarper1.SetupGraphics(&gBuffer[1]); + gWarper1.Clear(0.0, 0.0, 0.0, 1.0); + // Clear the screen to black. + gPreview.Clear(0.0, 0.0, 0.0, 1.0); + } + gPreviewBackground.Clear(0.0, 0.0, 0.0, 1.0); gLastTx = 0.0f; gPanOffset = 0.0f; gPanViewfinder = true; @@ -802,3 +866,9 @@ JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_updateMatrix( g_dTranslationToFBOCenterGL[i] = g_dTranslationToFBOCenter[i]; } } + +JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setPreviewBackground( + JNIEnv * env, jobject obj, jboolean flag) +{ + gPreviewBackgroundImage = (bool)flag; +} diff --git a/res/drawable-hdpi/ic_pan_progression.png b/res/drawable-hdpi/ic_pan_progression.png Binary files differindex 69650f0b7..b27714334 100644 --- a/res/drawable-hdpi/ic_pan_progression.png +++ b/res/drawable-hdpi/ic_pan_progression.png diff --git a/res/drawable-hdpi/ic_pan_progression_large.png b/res/drawable-hdpi/ic_pan_progression_large.png Binary files differindex afe91889f..a5ce53af0 100644 --- a/res/drawable-hdpi/ic_pan_progression_large.png +++ b/res/drawable-hdpi/ic_pan_progression_large.png diff --git a/res/drawable-hdpi/ic_pan_progression_xlarge.png b/res/drawable-hdpi/ic_pan_progression_xlarge.png Binary files differindex afe91889f..7892c504b 100644 --- a/res/drawable-hdpi/ic_pan_progression_xlarge.png +++ b/res/drawable-hdpi/ic_pan_progression_xlarge.png diff --git a/res/drawable-mdpi/ic_pan_progression.png b/res/drawable-mdpi/ic_pan_progression.png Binary files differindex 9425f324c..ee53169d2 100644 --- a/res/drawable-mdpi/ic_pan_progression.png +++ b/res/drawable-mdpi/ic_pan_progression.png diff --git a/res/drawable-mdpi/ic_pan_progression_xlarge.png b/res/drawable-mdpi/ic_pan_progression_xlarge.png Binary files differindex d75ec8bbe..218d2b35d 100644 --- a/res/drawable-mdpi/ic_pan_progression_xlarge.png +++ b/res/drawable-mdpi/ic_pan_progression_xlarge.png diff --git a/res/drawable-xhdpi/ic_pan_progression.png b/res/drawable-xhdpi/ic_pan_progression.png Binary files differindex 756edb71d..9610c2de5 100644 --- a/res/drawable-xhdpi/ic_pan_progression.png +++ b/res/drawable-xhdpi/ic_pan_progression.png diff --git a/res/drawable-xhdpi/ic_pan_progression_xlarge.png b/res/drawable-xhdpi/ic_pan_progression_xlarge.png Binary files differindex 22d8a4eed..91484d21c 100644 --- a/res/drawable-xhdpi/ic_pan_progression_xlarge.png +++ b/res/drawable-xhdpi/ic_pan_progression_xlarge.png diff --git a/res/layout/pano_module_capture.xml b/res/layout/pano_module_capture.xml index 6ab8c9e4b..ad34cf808 100644 --- a/res/layout/pano_module_capture.xml +++ b/res/layout/pano_module_capture.xml @@ -16,105 +16,114 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/panorama_capture_layout" - android:layout_height="match_parent" - android:layout_width="match_parent"> + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <FrameLayout + android:id="@+id/pano_preview_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" > + + <TextureView + android:id="@+id/pano_preview_textureview" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <View + android:id="@+id/pano_preview_area_border" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/ic_pan_border_fast" + android:visibility="gone" /> + </FrameLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical"> + android:orientation="vertical" > <!-- The top bar with capture indication --> <FrameLayout style="@style/PanoViewHorizontalBar" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1"> + android:layout_weight="1" > <TextView android:id="@+id/pano_capture_indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" android:text="@string/pano_capture_indication" android:textAppearance="?android:textAppearanceMedium" - android:layout_gravity="center" - android:visibility="gone" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:visibility="gone" /> </FrameLayout> - <FrameLayout - android:layout_gravity="center" - android:id="@+id/pano_preview_layout" - android:layout_weight="@integer/SRI_pano_layout_weight" + <View + android:id="@+id/pano_dummy_layout" android:layout_width="match_parent" - android:layout_height="0dp"> - - <TextureView - android:id="@+id/pano_preview_textureview" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - - <View - android:id="@+id/pano_preview_area_border" - android:visibility="gone" - android:background="@drawable/ic_pan_border_fast" - android:layout_width="match_parent" - android:layout_height="match_parent" /> - </FrameLayout> + android:layout_height="0dp" + android:layout_weight="@integer/SRI_pano_layout_weight" + android:visibility="invisible" /> <!-- The bottom bar with progress bar and direction indicators --> <FrameLayout android:id="@+id/pano_progress_layout" style="@style/PanoViewHorizontalBar" - android:paddingTop="20dp" - android:gravity="top" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_weight="1"> + android:layout_weight="1" + android:gravity="top" + android:paddingTop="20dp" > - <RelativeLayout + <LinearLayout android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <com.android.camera.PanoProgressBar - android:id="@+id/pano_pan_progress_bar" - android:visibility="gone" - android:src="@drawable/ic_pan_progression" - android:layout_centerInParent="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:layout_height="wrap_content" + android:layout_centerInParent="true" + android:orientation="horizontal" > <ImageView android:id="@+id/pano_pan_left_indicator" - android:src="@drawable/pano_direction_left_indicator" - android:visibility="gone" + android:layout_width="0dp" + android:layout_height="wrap_content" android:layout_marginRight="5dp" - android:layout_toLeftOf="@id/pano_pan_progress_bar" - android:layout_centerVertical="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> + android:layout_weight="1" + android:gravity="center_vertical" + android:src="@drawable/pano_direction_left_indicator" + android:visibility="gone" /> + + <com.android.camera.PanoProgressBar + android:id="@+id/pano_pan_progress_bar" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="9" + android:gravity="center_vertical" + android:src="@drawable/ic_pan_progression" + android:visibility="gone" /> <ImageView android:id="@+id/pano_pan_right_indicator" - android:src="@drawable/pano_direction_right_indicator" - android:visibility="gone" + android:layout_width="0dp" + android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_toRightOf="@id/pano_pan_progress_bar" - android:layout_centerVertical="true" - android:layout_width="wrap_content" - android:layout_height="wrap_content" /> - </RelativeLayout> + android:layout_weight="1" + android:gravity="center_vertical" + android:src="@drawable/pano_direction_right_indicator" + android:visibility="gone" /> + </LinearLayout> </FrameLayout> - - </LinearLayout> <!-- The hint for "Too fast" text view --> <TextView android:id="@+id/pano_capture_too_fast_textview" - android:text="@string/pano_too_fast_prompt" - android:textAppearance="?android:textAppearanceMedium" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:text="@string/pano_too_fast_prompt" + android:textAppearance="?android:textAppearanceMedium" android:visibility="gone" /> + </FrameLayout> diff --git a/res/values-port/dimensions.xml b/res/values-port/dimensions.xml index 67e3ebc3f..f47567a6c 100644 --- a/res/values-port/dimensions.xml +++ b/res/values-port/dimensions.xml @@ -14,6 +14,6 @@ limitations under the License. --> <resources> - <integer name="SRI_pano_layout_weight">2</integer> + <integer name="SRI_pano_layout_weight">3</integer> <dimen name="count_down_title_margin_top">90dp</dimen> </resources> diff --git a/res/values/config.xml b/res/values/config.xml index 24f790c4e..f83b5d8f4 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -23,4 +23,8 @@ <!-- This value may be tweaked to save memory on low RAM devices. The value is the percentage of camera preview height/width to scale to. --> <integer name="panorama_frame_size_reduction">100</integer> + + <!-- This value may be changed to true to enable the warped pano preview overlayed on top + of the fullscreen pano preview. --> + <bool name="enable_warped_pano_preview">true</bool> </resources> diff --git a/src/com/android/camera/MosaicPreviewRenderer.java b/src/com/android/camera/MosaicPreviewRenderer.java index 42da4d9e7..ba35b6f5a 100644 --- a/src/com/android/camera/MosaicPreviewRenderer.java +++ b/src/com/android/camera/MosaicPreviewRenderer.java @@ -34,6 +34,7 @@ public class MosaicPreviewRenderer { private int mHeight; // height of the view in UI private boolean mIsLandscape = true; + private int mOrientation = 0; private final float[] mTransformMatrix = new float[16]; private ConditionVariable mEglThreadBlockVar = new ConditionVariable(); @@ -43,13 +44,15 @@ public class MosaicPreviewRenderer { private SurfaceTexture mInputSurfaceTexture; + private boolean mEnableWarpedPanoPreview = false; + private class MyHandler extends Handler { public static final int MSG_INIT_SYNC = 0; public static final int MSG_SHOW_PREVIEW_FRAME_SYNC = 1; public static final int MSG_SHOW_PREVIEW_FRAME = 2; public static final int MSG_ALIGN_FRAME_SYNC = 3; public static final int MSG_RELEASE = 4; - + public static final int MSG_DO_PREVIEW_RESET = 5; public MyHandler(Looper looper) { super(looper); } @@ -65,6 +68,9 @@ public class MosaicPreviewRenderer { doShowPreviewFrame(); mEglThreadBlockVar.open(); break; + case MSG_DO_PREVIEW_RESET: + doPreviewReset(); + break; case MSG_SHOW_PREVIEW_FRAME: doShowPreviewFrame(); break; @@ -83,10 +89,13 @@ public class MosaicPreviewRenderer { mInputSurfaceTexture.updateTexImage(); mInputSurfaceTexture.getTransformMatrix(mTransformMatrix); - MosaicRenderer.setWarping(true); - // Call preprocess to render it to low-res and high-res RGB textures. + // Call setPreviewBackground to render high-res RGB textures to full screen. + MosaicRenderer.setPreviewBackground(true); MosaicRenderer.preprocess(mTransformMatrix); - // Now, transfer the textures from GPU to CPU memory for processing + MosaicRenderer.step(); + MosaicRenderer.setPreviewBackground(false); + + MosaicRenderer.setWarping(true); MosaicRenderer.transferGPUtoCPU(); MosaicRenderer.updateMatrix(); MosaicRenderer.step(); @@ -104,8 +113,12 @@ public class MosaicPreviewRenderer { } private void doInit() { - mInputSurfaceTexture = new SurfaceTexture(MosaicRenderer.init()); - MosaicRenderer.reset(mWidth, mHeight, mIsLandscape); + mInputSurfaceTexture = new SurfaceTexture(MosaicRenderer.init(mEnableWarpedPanoPreview)); + MosaicRenderer.reset(mWidth, mHeight, mIsLandscape, mOrientation); + } + + private void doPreviewReset() { + MosaicRenderer.reset(mWidth, mHeight, mIsLandscape, mOrientation); } private void doRelease() { @@ -134,9 +147,11 @@ public class MosaicPreviewRenderer { * @param isLandscape The UI orientation. {@code true} if in landscape, * false if in portrait. */ - public MosaicPreviewRenderer(SurfaceTexture tex, int w, int h, boolean isLandscape) { + public MosaicPreviewRenderer(SurfaceTexture tex, int w, int h, boolean isLandscape, + int orientation, boolean enableWarpedPanoPreview) { mIsLandscape = isLandscape; - + mOrientation = orientation; + mEnableWarpedPanoPreview = enableWarpedPanoPreview; mEglThread = new HandlerThread("PanoramaRealtimeRenderer"); mEglThread.start(); mHandler = new MyHandler(mEglThread.getLooper()); @@ -157,6 +172,15 @@ public class MosaicPreviewRenderer { mHandler.sendMessageSync(MyHandler.MSG_INIT_SYNC); } + public void previewReset(int w, int h, boolean isLandscape, int orientation) { + mWidth = w; + mHeight = h; + mIsLandscape = isLandscape; + mOrientation = orientation; + mHandler.sendEmptyMessage(MyHandler.MSG_DO_PREVIEW_RESET); + mSTRenderer.draw(false); + } + public void release() { mSTRenderer.release(); mHandler.sendMessageSync(MyHandler.MSG_RELEASE); diff --git a/src/com/android/camera/MosaicRenderer.java b/src/com/android/camera/MosaicRenderer.java index 92d9cb7b6..5006b364d 100644 --- a/src/com/android/camera/MosaicRenderer.java +++ b/src/com/android/camera/MosaicRenderer.java @@ -35,7 +35,7 @@ public class MosaicRenderer * @return textureID the texture ID of the newly generated texture to * be assigned to the SurfaceTexture object. */ - public static native int init(); + public static native int init(boolean mEnableWarpedPanoPreview); /** * Pass the drawing surface's width and height to initialize the @@ -44,8 +44,10 @@ public class MosaicRenderer * @param width width of the drawing surface in pixels. * @param height height of the drawing surface in pixels. * @param isLandscapeOrientation is the orientation of the activity layout in landscape. + * @param oientation is the orientation value in integer. */ - public static native void reset(int width, int height, boolean isLandscapeOrientation); + public static native void reset(int width, int height, + boolean isLandscapeOrientation, int orientation); /** * Calling this function will render the SurfaceTexture to a new 2D texture @@ -86,4 +88,14 @@ public class MosaicRenderer * @param flag boolean flag to set the warping to true or false. */ public static native void setWarping(boolean flag); + /** + * This function allows toggling between drawing the background full + * screen preview image data to screen and drawing the warped smaller + * preview on top of it. To render the full screen background preview, + * we set the falsg to true and to render the warped image on top of this + * we set the flag to false and flag in setWarping to true. + * + * @param flag boolean flag to set the warping to true or false. + */ + public static native void setPreviewBackground(boolean flag); } diff --git a/src/com/android/camera/PanoProgressBar.java b/src/com/android/camera/PanoProgressBar.java index 8dfb3660b..2a0589066 100644 --- a/src/com/android/camera/PanoProgressBar.java +++ b/src/com/android/camera/PanoProgressBar.java @@ -181,8 +181,5 @@ class PanoProgressBar extends ImageView { } canvas.drawRect(l, mDrawBounds.top, r, mDrawBounds.bottom, mIndicatorPaint); } - - // draw the mask image on the top for shaping. - super.onDraw(canvas); } } diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java index bad7073a9..eb66c8395 100644 --- a/src/com/android/camera/PhotoUI.java +++ b/src/com/android/camera/PhotoUI.java @@ -350,7 +350,7 @@ public class PhotoUI implements PieListener, mAspectRatioResize = true; mAspectRatio = ratio; } - mCameraControls.setPreviewRatio(mAspectRatio); + mCameraControls.setPreviewRatio(mAspectRatio, false); layoutPreview(ratio); } diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java index 13db502c5..b70027a80 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -369,7 +369,7 @@ public class VideoUI implements PieRenderer.PieListener, mHandler.sendEmptyMessage(UPDATE_TRANSFORM_MATRIX); } // ensure a semi-transparent background for now - mCameraControls.setPreviewRatio(1.0f); + mCameraControls.setPreviewRatio(1.0f, false); } public int getPreviewWidth() { diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java index 900951d96..e5ba57eb2 100644 --- a/src/com/android/camera/WideAnglePanoramaModule.java +++ b/src/com/android/camera/WideAnglePanoramaModule.java @@ -151,6 +151,7 @@ public class WideAnglePanoramaModule private ComboPreferences mPreferences; private boolean mMosaicPreviewConfigured; private boolean mPreviewFocused = true; + private boolean mPreviewLayoutChanged = false; @Override public void onPreviewUIReady() { @@ -205,6 +206,7 @@ public class WideAnglePanoramaModule } if (oldOrientation != mDeviceOrientation && oldOrientation != OrientationEventListener.ORIENTATION_UNKNOWN) { + mPreviewLayoutChanged = true; if (!mOrientationLocked) mUI.setOrientation(mDeviceOrientation, true); } @@ -250,6 +252,12 @@ public class WideAnglePanoramaModule mRootView.setVisibility(View.VISIBLE); } else { if (mCaptureState == CAPTURE_STATE_VIEWFINDER) { + if (mPreviewLayoutChanged) { + boolean isLandscape = (mDeviceOrientation / 90) % 2 == 1; + renderer.previewReset(mPreviewUIWidth, mPreviewUIHeight, + isLandscape, mDeviceOrientation); + mPreviewLayoutChanged = false; + } renderer.showPreviewFrame(); } else { renderer.alignFrameSync(); @@ -467,13 +475,13 @@ public class WideAnglePanoramaModule } mMosaicPreviewRenderer = null; } - final boolean isLandscape = - (mActivity.getResources().getConfiguration().orientation == - Configuration.ORIENTATION_LANDSCAPE); + final boolean isLandscape = (mDeviceOrientation / 90) % 2 == 1; + final boolean enableWarpedPanoPreview = + mActivity.getResources().getBoolean(R.bool.enable_warped_pano_preview); mUI.flipPreviewIfNeeded(); MosaicPreviewRenderer renderer = new MosaicPreviewRenderer( - mUI.getSurfaceTexture(), - mPreviewUIWidth, mPreviewUIHeight, isLandscape); + mUI.getSurfaceTexture(), mPreviewUIWidth, mPreviewUIHeight, + isLandscape, mDeviceOrientation, enableWarpedPanoPreview); synchronized (mRendererLock) { mMosaicPreviewRenderer = renderer; mCameraTexture = mMosaicPreviewRenderer.getInputSurfaceTexture(); diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java index 53b1630b1..7941ea88c 100644 --- a/src/com/android/camera/WideAnglePanoramaUI.java +++ b/src/com/android/camera/WideAnglePanoramaUI.java @@ -35,6 +35,7 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; import android.view.Gravity; +import android.view.Display; import android.view.LayoutInflater; import android.view.TextureView; import android.view.View; @@ -100,6 +101,7 @@ public class WideAnglePanoramaUI implements private View mPreviewCover; private int mOrientation; + private int mPreviewYOffset; /** Constructor. */ public WideAnglePanoramaUI( @@ -353,6 +355,39 @@ public class WideAnglePanoramaUI implements } } + private void setPanoramaPreviewView() { + int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); + Display display = mActivity.getWindowManager().getDefaultDisplay(); + Point size = new Point(); + display.getSize(size); + + int width = size.x; + int height = size.y; + int xOffset = 0; + int yOffset = 0; + int w = width; + int h = height; + + h = w * 4 / 3; + yOffset = (height - h) / 2; + + FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(w, h); + mTextureView.setLayoutParams(param); + mTextureView.setX(xOffset); + mTextureView.setY(yOffset); + mPreviewBorder.setLayoutParams(param); + mPreviewBorder.setX(xOffset); + mPreviewBorder.setY(yOffset); + mPreviewYOffset = yOffset; + + int t = mPreviewYOffset; + int b1 = mTextureView.getBottom() - mPreviewYOffset; + int r = mTextureView.getRight(); + int b2 = mTextureView.getBottom(); + + mCameraControls.setPreviewRatio(1.0f, true); + } + public void resetSavingProgress() { mSavingProgressBar.reset(); mSavingProgressBar.setRightIncreasing(true); @@ -441,6 +476,7 @@ public class WideAnglePanoramaUI implements mTextureView.setSurfaceTextureListener(this); mTextureView.addOnLayoutChangeListener(this); mCameraControls = (CameraControls) mRootView.findViewById(R.id.camera_controls); + setPanoramaPreviewView(); mDialogHelper = new DialogHelper(); setViews(appRes); @@ -449,14 +485,6 @@ public class WideAnglePanoramaUI implements private void setViews(Resources appRes) { int weight = appRes.getInteger(R.integer.SRI_pano_layout_weight); - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mPreviewLayout.getLayoutParams(); - lp.weight = weight; - mPreviewLayout.setLayoutParams(lp); - - lp = (LinearLayout.LayoutParams) mReview.getLayoutParams(); - lp.weight = weight; - mPreviewLayout.setLayoutParams(lp); - mSavingProgressBar = (PanoProgressBar) mRootView.findViewById(R.id.pano_saving_progress_bar); mSavingProgressBar.setIndicatorWidth(0); mSavingProgressBar.setMaxProgress(100); @@ -603,11 +631,11 @@ public class WideAnglePanoramaUI implements // | 3 | // `---------' =b2 // =r - int t = mPreviewLayout.getTop(); - int b1 = mPreviewLayout.getBottom(); - int r = mPreviewLayout.getRight(); - int b2 = mCaptureLayout.getBottom(); - + final View dummy = mRootView.findViewById(R.id.pano_dummy_layout); + int t = dummy.getTop(); + int b1 = dummy.getBottom(); + int r = dummy.getRight(); + int b2 = dummy.getBottom(); final FrameLayout progressLayout = (FrameLayout) mRootView.findViewById(R.id.pano_progress_layout); int pivotY = ((ViewGroup) progressLayout).getPaddingTop() diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index dedf3d583..59222b929 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -20,8 +20,8 @@ import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.content.Context; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.drawable.AnimationDrawable; -import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Paint; @@ -803,13 +803,17 @@ public class CameraControls extends RotatableLayout { mBottomMargin = bottom; } - public void setPreviewRatio(float ratio) { - int r = CameraUtil.determineRatio(ratio); - mPreviewRatio = r; - if (mPreviewRatio == CameraUtil.RATIO_4_3 && mTopMargin != 0) { - mPaint.setColor(getResources().getColor(R.color.camera_control_bg_opaque)); + public void setPreviewRatio(float ratio, boolean panorama) { + if (panorama) { + mPaint.setColor(Color.TRANSPARENT); } else { - mPaint.setColor(getResources().getColor(R.color.camera_control_bg_transparent)); + int r = CameraUtil.determineRatio(ratio); + mPreviewRatio = r; + if (mPreviewRatio == CameraUtil.RATIO_4_3 && mTopMargin != 0) { + mPaint.setColor(getResources().getColor(R.color.camera_control_bg_opaque)); + } else { + mPaint.setColor(getResources().getColor(R.color.camera_control_bg_transparent)); + } } invalidate(); } |