mosaic_renderer_jni.cpp revision 4fabf52f7e8b2419749f5cdc03925d5f8b1c0199
1274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen/* 2274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Copyright (C) 2011 The Android Open Source Project 3274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * 4274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * you may not use this file except in compliance with the License. 6274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * You may obtain a copy of the License at 7274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * 8274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 9274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * 10274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Unless required by applicable law or agreed to in writing, software 11274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 12274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * See the License for the specific language governing permissions and 14274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * limitations under the License. 15274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen */ 16274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen 17274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include <GLES2/gl2.h> 18274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include <GLES2/gl2ext.h> 19eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <jni.h> 20274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include <math.h> 21274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include <stdio.h> 22274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include <stdlib.h> 23274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include "db_utilities_camera.h" 24eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic/ImageUtils.h" 25eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer/FrameBuffer.h" 26eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer/WarpRenderer.h" 2741a2e9735136f372de95652d0828600282c8e967mbansal#include "mosaic_renderer/SurfaceTextureRenderer.h" 281e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#include "mosaic_renderer/YVURenderer.h" 29eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 30274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include "mosaic/Log.h" 31274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#define LOG_TAG "MosaicRenderer" 32eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 33274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen#include "mosaic_renderer_jni.h" 34eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 35eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Texture handle 3641a2e9735136f372de95652d0828600282c8e967mbansalGLuint gSurfaceTextureID[1]; 37eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 3841a2e9735136f372de95652d0828600282c8e967mbansalbool gWarpImage = true; 39eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 401e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Low-Res input image frame in YUVA format for preview rendering and processing 411e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// and high-res YUVA input image for processing. 421e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalunsigned char* gPreviewImage[NR]; 4341a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res & high-res preview image width 441e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalint gPreviewImageWidth[NR]; 4541a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res & high-res preview image height 461e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalint gPreviewImageHeight[NR]; 47eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 481e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Semaphore to protect simultaneous read/writes from gPreviewImage 491e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalsem_t gPreviewImage_semaphore; 50eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 51eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen preview FBO width (large enough to store the entire 52eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// preview mosaic). 53eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint gPreviewFBOWidth; 54eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen preview FBO height (large enough to store the entire 55eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// preview mosaic). 56eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint gPreviewFBOHeight; 57eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 58a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// gK is the transformation to map the canonical {-1,1} vertex coordinate system 59a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// to the {0,gPreviewImageWidth[LR]} input image frame coordinate system before 60a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// applying the given affine transformation trs. gKm is the corresponding 61a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// transformation for going to the {0,gPreviewFBOWidth}. 62a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gK[9]; 63a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gKinv[9]; 64a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gKm[9]; 65a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gKminv[9]; 66a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 6741a2e9735136f372de95652d0828600282c8e967mbansal// Shader to copy input SurfaceTexture into and RGBA FBO. The two shaders 6841a2e9735136f372de95652d0828600282c8e967mbansal// render to the textures with dimensions corresponding to the low-res and 6941a2e9735136f372de95652d0828600282c8e967mbansal// high-res image frames. 7041a2e9735136f372de95652d0828600282c8e967mbansalSurfaceTextureRenderer gSurfTexRenderer[NR]; 7141a2e9735136f372de95652d0828600282c8e967mbansal// Off-screen FBOs to store the low-res and high-res RGBA copied out from 7241a2e9735136f372de95652d0828600282c8e967mbansal// the SurfaceTexture by the gSurfTexRenderers. 7341a2e9735136f372de95652d0828600282c8e967mbansalFrameBuffer gBufferInput[NR]; 741e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Shader to convert RGBA textures into YVU textures for processing 761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalYVURenderer gYVURenderer[NR]; 771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Off-screen FBOs to store the low-res and high-res YVU textures for processing 781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalFrameBuffer gBufferInputYVU[NR]; 791e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 8047f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen// Shader to translate the flip-flop FBO - gBuffer[1-current] -> gBuffer[current] 811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalWarpRenderer gWarper1; 8247f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen// Shader to add warped current frame to the flip-flop FBO - gBuffer[current] 831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalWarpRenderer gWarper2; 841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Off-screen FBOs (flip-flop) to store the result of gWarper1 & gWarper2 851e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalFrameBuffer gBuffer[2]; 861e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 87eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Shader to warp and render the preview FBO to the screen 88eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalWarpRenderer gPreview; 891e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 901e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Index of the gBuffer FBO gWarper1 is going to write into 911e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalint gCurrentFBOIndex = 0; 921e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 93a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// 3x3 Matrices holding the transformation of this frame (gThisH1t) and of 94a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// the last frame (gLastH1t) w.r.t the first frame. 95a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gThisH1t[9]; 96a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gLastH1t[9]; 97a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 98a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// Variables to represent the fixed position of the top-left corner of the 99a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// current frame in the previewFBO 100a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gCenterOffsetX = 0.0f; 101a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gCenterOffsetY = 0.0f; 102a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 103a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// X-Offset of the viewfinder (current frame) w.r.t 104a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// (gCenterOffsetX, gCenterOffsetY). This offset varies with time and is 105a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// used to pan the viewfinder across the UI layout. 106a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gPanOffset = 0.0f; 1071e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1081e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Variables tracking the translation value for the current frame and the 1091e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// last frame (both w.r.t the first frame). The difference between these 1101e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// values is used to control the panning speed of the viewfinder display 1111e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// on the UI screen. 1121e762b1f935c9d4a06af6dd56121590ca81d48b1mbansaldouble gThisTx = 0.0f; 1131e762b1f935c9d4a06af6dd56121590ca81d48b1mbansaldouble gLastTx = 0.0f; 114eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 115a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// These are the scale factors used by the gPreview shader to ensure that 116a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// the image frame is correctly scaled to the full UI layout height while 117a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// maintaining its aspect ratio 118a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gUILayoutScalingX = 1.0f; 119a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble gUILayoutScalingY = 1.0f; 120a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 121d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen// Whether the view that we will render preview FBO onto is in landscape or portrait 122d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen// orientation. 123d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenbool gIsLandscapeOrientation = true; 124d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 125a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// State of the viewfinder. Set to false when the viewfinder hits the UI edge. 126a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansalbool gPanViewfinder = true; 127a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 128eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Affine transformation in GL 4x4 format (column-major) to warp the 129a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// last frame mosaic into the current frame coordinate system. 130eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransGL[16]; 131a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble g_dAffinetrans[16]; 132eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 133a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// Affine transformation in GL 4x4 format (column-major) to translate the 134a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// preview FBO across the screen (viewfinder panning). 135a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansalGLfloat g_dAffinetransPanGL[16]; 136a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble g_dAffinetransPan[16]; 137eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 138a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// XY translation in GL 4x4 format (column-major) to center the current 139a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// preview mosaic in the preview FBO 140a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansalGLfloat g_dTranslationToFBOCenterGL[16]; 141a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansaldouble g_dTranslationToFBOCenter[16]; 1421e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 143eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// GL 4x4 Identity transformation 144d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta ChenGLfloat g_dAffinetransIdentGL[] = { 145eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 1., 0., 0., 0., 146eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0., 1., 0., 0., 147eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0., 0., 1., 0., 148eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0., 0., 0., 1.}; 149eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 150d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen// GL 4x4 Rotation transformation (column-majored): 90 degree 151d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta ChenGLfloat g_dAffinetransRotation90GL[] = { 152d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 0., 1., 0., 0., 153d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen -1., 0., 0., 0., 154d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 0., 0., 1., 0., 155d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 0., 0., 0., 1.}; 156d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 157d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen// 3x3 Rotation transformation (row-majored): 90 degree 158d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chendouble gRotation90[] = { 159d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 0., -1., 0., 160d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 1., 0., 0., 161d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 0., 0., 1.,}; 162d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 163d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 1641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalfloat g_dIdent3x3[] = { 1651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1.0, 0.0, 0.0, 1661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 0.0, 1.0, 0.0, 1671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 0.0, 0.0, 1.0}; 1681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 16941a2e9735136f372de95652d0828600282c8e967mbansalconst int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65; 170eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 171eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalstatic void printGLString(const char *name, GLenum s) { 172eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal const char *v = (const char *) glGetString(s); 173274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen LOGI("GL %s = %s", name, v); 174eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 175eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 1764fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kongvoid checkFramebufferStatus(const char* name) { 1774fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 1784fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong if (status == 0) { 1794fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong LOGE("Checking completeness of Framebuffer:%s", name); 1804fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong checkGlError("checkFramebufferStatus (is the target \"GL_FRAMEBUFFER\"?)"); 1814fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong } else if (status != GL_FRAMEBUFFER_COMPLETE) { 1824fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong const char* msg = "not listed"; 1834fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong switch (status) { 1844fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: msg = "attachment"; break; 1854fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: msg = "dimensions"; break; 1864fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: msg = "missing attachment"; break; 1874fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_FRAMEBUFFER_UNSUPPORTED: msg = "unsupported"; break; 1884fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong } 1894fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong LOGE("Framebuffer: %s is INCOMPLETE: %s, %x", name, msg, status); 1904fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong } 1914fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong} 1924fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong 193eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// @return false if there was an error 1944fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kongbool checkGLErrorDetail(const char* file, int line, const char* op) { 195eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal GLint error = glGetError(); 1964fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong const char* err_msg = "NOT_LISTED"; 197eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (error != 0) { 1984fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong switch (error) { 1994fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_INVALID_VALUE: err_msg = "NOT_LISTED_YET"; break; 2004fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_INVALID_OPERATION: err_msg = "INVALID_OPERATION"; break; 2014fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong case GL_INVALID_ENUM: err_msg = "INVALID_ENUM"; break; 2024fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong } 2034fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong LOGE("Error after %s(). glError: %s (0x%x) in line %d of %s", op, err_msg, error, line, file); 204eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return false; 205eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 206eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return true; 207eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 208eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 20941a2e9735136f372de95652d0828600282c8e967mbansalvoid bindSurfaceTexture(GLuint texId) 210eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 21141a2e9735136f372de95652d0828600282c8e967mbansal glBindTexture(GL_TEXTURE_EXTERNAL_OES_ENUM, texId); 21241a2e9735136f372de95652d0828600282c8e967mbansal 21341a2e9735136f372de95652d0828600282c8e967mbansal // Can't do mipmapping with camera source 21441a2e9735136f372de95652d0828600282c8e967mbansal glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MIN_FILTER, 21541a2e9735136f372de95652d0828600282c8e967mbansal GL_LINEAR); 21641a2e9735136f372de95652d0828600282c8e967mbansal glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MAG_FILTER, 21741a2e9735136f372de95652d0828600282c8e967mbansal GL_LINEAR); 21841a2e9735136f372de95652d0828600282c8e967mbansal // Clamp to edge is the only option 21941a2e9735136f372de95652d0828600282c8e967mbansal glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_S, 22041a2e9735136f372de95652d0828600282c8e967mbansal GL_CLAMP_TO_EDGE); 22141a2e9735136f372de95652d0828600282c8e967mbansal glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_T, 22241a2e9735136f372de95652d0828600282c8e967mbansal GL_CLAMP_TO_EDGE); 223eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 224eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 2251e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid ClearPreviewImage(int mID) 226eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 2271e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal unsigned char* ptr = gPreviewImage[mID]; 22841a2e9735136f372de95652d0828600282c8e967mbansal for(int j = 0, i = 0; 2291e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal j < gPreviewImageWidth[mID] * gPreviewImageHeight[mID] * 4; 23041a2e9735136f372de95652d0828600282c8e967mbansal j += 4) 23141a2e9735136f372de95652d0828600282c8e967mbansal { 23241a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 23341a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 23441a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 23541a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 255; 23641a2e9735136f372de95652d0828600282c8e967mbansal } 23741a2e9735136f372de95652d0828600282c8e967mbansal 238eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 239eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 240eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid ConvertAffine3x3toGL4x4(double *matGL44, double *mat33) 241eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 242eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[0] = mat33[0]; 243eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[1] = mat33[3]; 244eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[2] = 0.0; 245eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[3] = mat33[6]; 246eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 247eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[4] = mat33[1]; 248eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[5] = mat33[4]; 249eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[6] = 0.0; 250eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[7] = mat33[7]; 251eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 252eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[8] = 0; 253eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[9] = 0; 254eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[10] = 1.0; 255eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[11] = 0.0; 256eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 257eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[12] = mat33[2]; 258eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[13] = mat33[5]; 259eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[14] = 0.0; 260eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[15] = mat33[8]; 261eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 262eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 263d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenbool continuePanningFBO(double panOffset) { 264d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedScreenLimitLeft = -1.0 + VIEWPORT_BORDER_FACTOR_HORZ * 2.0; 265d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedScreenLimitRight = 1.0 - VIEWPORT_BORDER_FACTOR_HORZ * 2.0; 266d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedXPositionOnScreenLeft; 267d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedXPositionOnScreenRight; 268d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 269d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Compute the position of the current frame in the screen coordinate system 270d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (gIsLandscapeOrientation) { 271d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenLeft = (2.0 * 272d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen (gCenterOffsetX + panOffset) / gPreviewFBOWidth - 1.0) * 273d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingX; 274d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenRight = (2.0 * 275d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ((gCenterOffsetX + panOffset) + gPreviewImageWidth[HR]) / 276d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreviewFBOWidth - 1.0) * gUILayoutScalingX; 277d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 278d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenLeft = (2.0 * 279d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen (gCenterOffsetX + panOffset) / gPreviewFBOWidth - 1.0) * 280d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingY; 281d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenRight = (2.0 * 282d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ((gCenterOffsetX + panOffset) + gPreviewImageWidth[HR]) / 283d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreviewFBOWidth - 1.0) * gUILayoutScalingY; 284d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 285d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 286d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Stop the viewfinder panning if we hit the maximum border allowed for 287d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // this UI layout 288d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (normalizedXPositionOnScreenRight > normalizedScreenLimitRight || 289d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenLeft < normalizedScreenLimitLeft) { 290d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen return false; 291d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 292d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen return true; 293d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 294d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen} 295d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 2961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// This function computes fills the 4x4 matrices g_dAffinetrans, 297a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// and g_dAffinetransPan using the specified 3x3 affine 2981e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// transformation between the first captured frame and the current frame. 299a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// The computed g_dAffinetrans is such that it warps the preview mosaic in 300a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// the last frame's coordinate system into the coordinate system of the 301a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// current frame. Thus, applying this transformation will create the current 302a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// frame mosaic but with the current frame missing. This frame will then be 303a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// pasted in by gWarper2 after translating it by g_dTranslationToFBOCenter. 304a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// The computed g_dAffinetransPan is such that it offsets the computed preview 305a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// mosaic horizontally to make the viewfinder pan within the UI layout. 306eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid UpdateWarpTransformation(float *trs) 307eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 308a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal double H[9], Hp[9], Htemp1[9], Htemp2[9], T[9]; 309eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 310a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal for(int i = 0; i < 9; i++) 311eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 312a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gThisH1t[i] = trs[i]; 313eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 314eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 31547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Alignment is done based on low-res data. 31647f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // To render the preview mosaic, the translation of the high-res mosaic is estimated to 31747f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // H2L_FACTOR x low-res-based tranlation. 31847f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gThisH1t[2] *= H2L_FACTOR; 31947f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gThisH1t[5] *= H2L_FACTOR; 32047f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen 321a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(T); 322a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[2] = -gCenterOffsetX; 323a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[5] = -gCenterOffsetY; 324a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 325a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // H = ( inv(gThisH1t) * gLastH1t ) * T 326a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp1); 327a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp2); 328a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(H); 329a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_InvertAffineTransform(Htemp1, gThisH1t); 330a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Htemp2, Htemp1, gLastH1t); 331a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(H, Htemp2, T); 332a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 333a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal for(int i = 0; i < 9; i++) 334a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal { 335a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gLastH1t[i] = gThisH1t[i]; 336a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal } 3371e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 338eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Move the origin such that the frame is centered in the previewFBO 339a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // i.e. H = inv(T) * H 340a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal H[2] += gCenterOffsetX; 341a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal H[5] += gCenterOffsetY; 342eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 34347f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Hp = inv(Km) * H * Km 34447f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Km moves the coordinate system from openGL to image pixels so 3451e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // that the alignment transform H can be applied to them. 34647f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // inv(Km) moves the coordinate system back to openGL normalized 3471e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // coordinates so that the shader can correctly render it. 348a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp1); 349a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Htemp1, H, gKm); 350a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Hp, gKminv, Htemp1); 351eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 352eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal ConvertAffine3x3toGL4x4(g_dAffinetrans, Hp); 353eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 354a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal //////////////////////////////////////////////// 355a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////// Compute g_dAffinetransPan now... ////// 356a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal //////////////////////////////////////////////// 357eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 358a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gThisTx = trs[2]; 359eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 360a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal if(gPanViewfinder) 361a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal { 362a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanOffset += (gThisTx - gLastTx) * VIEWFINDER_PAN_FACTOR_HORZ; 363a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal } 3641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 3651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gLastTx = gThisTx; 366d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPanViewfinder = continuePanningFBO(gPanOffset); 367eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 368a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(H); 369a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal H[2] = gPanOffset; 3701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 37147f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Hp = inv(Km) * H * Km 372a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp1); 373a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Htemp1, H, gKm); 374a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Hp, gKminv, Htemp1); 3751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 376d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (gIsLandscapeOrientation) { 377d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ConvertAffine3x3toGL4x4(g_dAffinetransPan, Hp); 378d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 379d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // rotate Hp by 90 degress. 380d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen db_Multiply3x3_3x3(Htemp1, gRotation90, Hp); 381d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ConvertAffine3x3toGL4x4(g_dAffinetransPan, Htemp1); 382d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 383eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 384eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 38541a2e9735136f372de95652d0828600282c8e967mbansalvoid AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) 386eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 3871e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageWidth[HR] = widthHR; 3881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR] = heightHR; 3891e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 3901e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageWidth[LR] = widthLR; 3911e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR] = heightLR; 39241a2e9735136f372de95652d0828600282c8e967mbansal 3931e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 3941e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[LR] = ImageUtils::allocateImage(gPreviewImageWidth[LR], 3951e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR], 4); 3961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[HR] = ImageUtils::allocateImage(gPreviewImageWidth[HR], 3971e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR], 4); 3981e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 399eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 40047f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[HR]; 40147f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[HR]; 402eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 403a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // The origin is such that the current frame will sit with its center 404a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // at the center of the previewFBO 40547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[HR] / 2); 40647f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[HR] / 2); 407a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 408a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanOffset = 0.0f; 409a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 410a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gThisH1t); 411a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gLastH1t); 412a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 413a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanViewfinder = true; 414a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 41547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen int w = gPreviewImageWidth[HR]; 41647f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen int h = gPreviewImageHeight[HR]; 417a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 418a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal int wm = gPreviewFBOWidth; 419a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal int hm = gPreviewFBOHeight; 420a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 421a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // K is the transformation to map the canonical [-1,1] vertex coordinate 422a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // system to the [0,w] image coordinate system before applying the given 423a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // affine transformation trs. 424a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[0] = wm / 2.0 - 0.5; 425a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[1] = 0.0; 426a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[2] = wm / 2.0 - 0.5; 427a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[3] = 0.0; 428a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[4] = hm / 2.0 - 0.5; 429a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[5] = hm / 2.0 - 0.5; 430a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[6] = 0.0; 431a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[7] = 0.0; 432a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[8] = 1.0; 433a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 434a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[0] = w / 2.0 - 0.5; 435a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[1] = 0.0; 436a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[2] = w / 2.0 - 0.5; 437a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[3] = 0.0; 438a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[4] = h / 2.0 - 0.5; 439a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[5] = h / 2.0 - 0.5; 440a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[6] = 0.0; 441a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[7] = 0.0; 442a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[8] = 1.0; 443a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 444a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gKinv); 445a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_InvertCalibrationMatrix(gKinv, gK); 446a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 447a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gKminv); 448a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_InvertCalibrationMatrix(gKminv, gKm); 449a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 450a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////////////////////////////////////////// 451a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////// Compute g_Translation now... ////// 452a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////////////////////////////////////////// 453a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal double T[9], Tp[9], Ttemp[9]; 454a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 455a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(T); 456a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[2] = gCenterOffsetX; 457a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[5] = gCenterOffsetY; 458a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 459a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Tp = inv(K) * T * K 460a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Ttemp); 461a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Ttemp, T, gK); 462a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Tp, gKinv, Ttemp); 463a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 464a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ConvertAffine3x3toGL4x4(g_dTranslationToFBOCenter, Tp); 465eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 4661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal UpdateWarpTransformation(g_dIdent3x3); 467eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 468eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 469eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid FreeTextureMemory() 470eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 4711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 4721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ImageUtils::freeImage(gPreviewImage[LR]); 4731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ImageUtils::freeImage(gPreviewImage[HR]); 4741e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 475eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 476eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 477eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalextern "C" 478eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 479f93198f838d047572a5cdeaa66668b060985b937Angus Kong JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); 480f93198f838d047572a5cdeaa66668b060985b937Angus Kong JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved); 4810f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( 482eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 4830f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( 484d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen JNIEnv * env, jobject obj, jint width, jint height, 485d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen jboolean isLandscapeOrientation); 4860f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( 48741a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jfloatArray stMatrix); 4880f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_transferGPUtoCPU( 48941a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj); 4900f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step( 491eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 4924fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_updateMatrix( 493eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 4940f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( 49541a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jboolean flag); 496eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}; 497eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 498f93198f838d047572a5cdeaa66668b060985b937Angus Kong 499f93198f838d047572a5cdeaa66668b060985b937Angus KongJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) 500f93198f838d047572a5cdeaa66668b060985b937Angus Kong{ 501f93198f838d047572a5cdeaa66668b060985b937Angus Kong sem_init(&gPreviewImage_semaphore, 0, 1); 502f93198f838d047572a5cdeaa66668b060985b937Angus Kong 503f93198f838d047572a5cdeaa66668b060985b937Angus Kong return JNI_VERSION_1_4; 504f93198f838d047572a5cdeaa66668b060985b937Angus Kong} 505f93198f838d047572a5cdeaa66668b060985b937Angus Kong 506f93198f838d047572a5cdeaa66668b060985b937Angus Kong 507f93198f838d047572a5cdeaa66668b060985b937Angus KongJNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) 508f93198f838d047572a5cdeaa66668b060985b937Angus Kong{ 509f93198f838d047572a5cdeaa66668b060985b937Angus Kong sem_destroy(&gPreviewImage_semaphore); 510f93198f838d047572a5cdeaa66668b060985b937Angus Kong} 5110f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( 512eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 513eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 51441a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].InitializeGLProgram(); 51541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].InitializeGLProgram(); 5161e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].InitializeGLProgram(); 5171e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].InitializeGLProgram(); 5181e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.InitializeGLProgram(); 5191e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.InitializeGLProgram(); 520eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.InitializeGLProgram(); 5211e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[0].InitializeGLContext(); 5221e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[1].InitializeGLContext(); 52341a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].InitializeGLContext(); 52441a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].InitializeGLContext(); 5251e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[LR].InitializeGLContext(); 5261e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[HR].InitializeGLContext(); 527eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 528eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glBindFramebuffer(GL_FRAMEBUFFER, 0); 52941a2e9735136f372de95652d0828600282c8e967mbansal 53041a2e9735136f372de95652d0828600282c8e967mbansal glGenTextures(1, gSurfaceTextureID); 53141a2e9735136f372de95652d0828600282c8e967mbansal // bind the surface texture 53241a2e9735136f372de95652d0828600282c8e967mbansal bindSurfaceTexture(gSurfaceTextureID[0]); 53341a2e9735136f372de95652d0828600282c8e967mbansal 53441a2e9735136f372de95652d0828600282c8e967mbansal return (jint) gSurfaceTextureID[0]; 535eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 536eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 53741a2e9735136f372de95652d0828600282c8e967mbansal 538d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenvoid calculateUILayoutScaling(int width, int height, bool isLandscape) { 539d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (isLandscape) { 540d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // __________ ______ 541d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // |__________| => |______| 542d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // (Preview FBO) (View) 543d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // 544d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Scale the preview FBO's height to the height of view and 545d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // maintain the aspect ratio of the current frame on the screen. 546d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE; 547d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 548d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Note that OpenGL scales a texture to view's width and height automatically. 549d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // The "width / height" inverts the scaling, so as to maintain the aspect ratio 550d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // of the current frame. 551d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingX = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]) 552d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE) 553d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / ((float) width / height); 554d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 555d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // __ 556d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // __________ | | 557d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // |__________| => | | 558d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // (Preview FBO) | | 559d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // |__| 560d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // (View) 561d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Scale the preview FBO's height to the width of view and 562d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // maintain the aspect ratio of the current frame on the screen. 563d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingX = PREVIEW_FBO_HEIGHT_SCALE; 564d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 565d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Note that OpenGL scales a texture to view's width and height automatically. 566d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // The "height / width" inverts the scaling, so as to maintain the aspect ratio 567d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // of the current frame. 568d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingY = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]) 569d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE) 570d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / ((float) height / width); 571d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 572d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 573d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen} 574d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 5750f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( 576d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen JNIEnv * env, jobject obj, jint width, jint height, jboolean isLandscapeOrientation) 577eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 578d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gIsLandscapeOrientation = isLandscapeOrientation; 579d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen calculateUILayoutScaling(width, height, gIsLandscapeOrientation); 58085dedb803016feea39a78efc4bfc07b4f436cc6cWei-Ta Chen 5811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); 5821e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); 5831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 5841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInput[LR].Init(gPreviewImageWidth[LR], 5851e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR], GL_RGBA); 5861e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 5871e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInput[HR].Init(gPreviewImageWidth[HR], 5881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR], GL_RGBA); 58941a2e9735136f372de95652d0828600282c8e967mbansal 5901e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[LR].Init(gPreviewImageWidth[LR], 5911e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR], GL_RGBA); 59241a2e9735136f372de95652d0828600282c8e967mbansal 5931e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[HR].Init(gPreviewImageWidth[HR], 5941e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR], GL_RGBA); 595eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 59641a2e9735136f372de95652d0828600282c8e967mbansal // bind the surface texture 59741a2e9735136f372de95652d0828600282c8e967mbansal bindSurfaceTexture(gSurfaceTextureID[0]); 59841a2e9735136f372de95652d0828600282c8e967mbansal 599b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // To speed up, there is no need to clear the destination buffers 600b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // (offscreen/screen buffers) of gSurfTexRenderer, gYVURenderer 601b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // and gPreview because we always fill the whole destination buffers 602b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // when we draw something to those offscreen/screen buffers. 60341a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetupGraphics(&gBufferInput[LR]); 60441a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetViewportMatrix(1, 1, 1, 1); 60541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetScalingMatrix(1.0f, -1.0f); 60641a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetInputTextureName(gSurfaceTextureID[0]); 60741a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM); 608eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 60941a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetupGraphics(&gBufferInput[HR]); 61041a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetViewportMatrix(1, 1, 1, 1); 61141a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetScalingMatrix(1.0f, -1.0f); 61241a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetInputTextureName(gSurfaceTextureID[0]); 61341a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM); 61441a2e9735136f372de95652d0828600282c8e967mbansal 6151e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].SetupGraphics(&gBufferInputYVU[LR]); 6161e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].SetInputTextureName(gBufferInput[LR].GetTextureName()); 6171e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].SetInputTextureType(GL_TEXTURE_2D); 6181e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6191e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].SetupGraphics(&gBufferInputYVU[HR]); 6201e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].SetInputTextureName(gBufferInput[HR].GetTextureName()); 6211e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].SetInputTextureType(GL_TEXTURE_2D); 6221e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 623a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // gBuffer[1-gCurrentFBOIndex] --> gWarper1 --> gBuffer[gCurrentFBOIndex] 6241e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 625b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen 626b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // Clear the destination buffer of gWarper1. 6271e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 628a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetViewportMatrix(1, 1, 1, 1); 6291e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetScalingMatrix(1.0f, 1.0f); 630a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName()); 6311e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetInputTextureType(GL_TEXTURE_2D); 6321e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 63347f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // gBufferInput[HR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] 634a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 635b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen 636b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // gWarp2's destination buffer is the same to gWarp1's. No need to clear it 637b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // again. 63847f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gWarper2.SetViewportMatrix(gPreviewImageWidth[HR], 63947f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gPreviewImageHeight[HR], gBuffer[gCurrentFBOIndex].GetWidth(), 640a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gBuffer[gCurrentFBOIndex].GetHeight()); 6411e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.SetScalingMatrix(1.0f, 1.0f); 64247f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gWarper2.SetInputTextureName(gBufferInput[HR].GetTextureName()); 6431e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.SetInputTextureType(GL_TEXTURE_2D); 644eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 645b96ce59e1d477622f9a3c235135d7040f642e262Wei-Ta Chen // gBuffer[gCurrentFBOIndex] --> gPreview --> Screen 6464fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong // TODO: check the logic here to make sure the orientation is handled 6474fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong // correctly. 6484fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong // if (gIsLandscapeOrientation) gPreview.SetupGraphics(height, width); 6494fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong // else gPreview.SetupGraphics(width, height); 650eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetupGraphics(width, height); 651eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetViewportMatrix(1, 1, 1, 1); 652d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 6531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // Scale the previewFBO so that the viewfinder window fills the layout height 6541e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // while maintaining the image aspect ratio 655a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY); 656a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); 65741a2e9735136f372de95652d0828600282c8e967mbansal gPreview.SetInputTextureType(GL_TEXTURE_2D); 65841a2e9735136f372de95652d0828600282c8e967mbansal} 65941a2e9735136f372de95652d0828600282c8e967mbansal 6600f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( 66141a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jfloatArray stMatrix) 66241a2e9735136f372de95652d0828600282c8e967mbansal{ 66341a2e9735136f372de95652d0828600282c8e967mbansal jfloat *stmat = env->GetFloatArrayElements(stMatrix, 0); 66441a2e9735136f372de95652d0828600282c8e967mbansal 66541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetSTMatrix((float*) stmat); 66641a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetSTMatrix((float*) stmat); 66741a2e9735136f372de95652d0828600282c8e967mbansal 66841a2e9735136f372de95652d0828600282c8e967mbansal env->ReleaseFloatArrayElements(stMatrix, stmat, 0); 66941a2e9735136f372de95652d0828600282c8e967mbansal 670d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gSurfTexRenderer[LR].DrawTexture(g_dAffinetransIdentGL); 671d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gSurfTexRenderer[HR].DrawTexture(g_dAffinetransIdentGL); 67241a2e9735136f372de95652d0828600282c8e967mbansal} 67341a2e9735136f372de95652d0828600282c8e967mbansal 6741e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#ifndef now_ms 6751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#include <time.h> 6761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalstatic double 6771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalnow_ms(void) 6781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 6791e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal //struct timespec res; 6801e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal struct timeval res; 6811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal //clock_gettime(CLOCK_REALTIME, &res); 6821e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gettimeofday(&res, NULL); 6831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return 1000.0*res.tv_sec + (double)res.tv_usec/1e3; 6841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 6851e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#endif 6861e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6871e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6890f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_transferGPUtoCPU( 69041a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj) 69141a2e9735136f372de95652d0828600282c8e967mbansal{ 6921e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal double t0, t1, time_c; 6931e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6941e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].DrawTexture(); 6951e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].DrawTexture(); 6961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6971e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 69841a2e9735136f372de95652d0828600282c8e967mbansal // Bind to the input LR FBO and read the Low-Res data from there... 6991e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glBindFramebuffer(GL_FRAMEBUFFER, gBufferInputYVU[LR].GetFrameBufferName()); 7001e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal t0 = now_ms(); 70141a2e9735136f372de95652d0828600282c8e967mbansal glReadPixels(0, 70241a2e9735136f372de95652d0828600282c8e967mbansal 0, 70341a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].GetWidth(), 70441a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].GetHeight(), 70541a2e9735136f372de95652d0828600282c8e967mbansal GL_RGBA, 70641a2e9735136f372de95652d0828600282c8e967mbansal GL_UNSIGNED_BYTE, 7071e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[LR]); 70841a2e9735136f372de95652d0828600282c8e967mbansal 7094fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong checkGlError("glReadPixels LR (MosaicRenderer.transferGPUtoCPU())"); 71041a2e9735136f372de95652d0828600282c8e967mbansal 71141a2e9735136f372de95652d0828600282c8e967mbansal // Bind to the input HR FBO and read the high-res data from there... 7121e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glBindFramebuffer(GL_FRAMEBUFFER, gBufferInputYVU[HR].GetFrameBufferName()); 7131e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal t0 = now_ms(); 71441a2e9735136f372de95652d0828600282c8e967mbansal glReadPixels(0, 71541a2e9735136f372de95652d0828600282c8e967mbansal 0, 71641a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].GetWidth(), 71741a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].GetHeight(), 71841a2e9735136f372de95652d0828600282c8e967mbansal GL_RGBA, 71941a2e9735136f372de95652d0828600282c8e967mbansal GL_UNSIGNED_BYTE, 7201e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[HR]); 72141a2e9735136f372de95652d0828600282c8e967mbansal 7224fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus Kong checkGlError("glReadPixels HR (MosaicRenderer.transferGPUtoCPU())"); 72341a2e9735136f372de95652d0828600282c8e967mbansal 7241e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 725eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 726eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7270f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step( 728eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 729eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 730a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal if(!gWarpImage) // ViewFinder 7311e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 732a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 7331e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); 7341e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 735a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); 736d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 737d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (gIsLandscapeOrientation) { 738d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreview.DrawTexture(g_dAffinetransIdentGL); 739d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 740d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreview.DrawTexture(g_dAffinetransRotation90GL); 741d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 7421e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 7431e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal else 7441e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 7451e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 746a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Clear the destination so that we can paint on it afresh 747a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 748a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetInputTextureName( 749a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gBuffer[1 - gCurrentFBOIndex].GetTextureName()); 750a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 751a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); 752eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.DrawTexture(g_dAffinetransGL); 754a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); 755a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.DrawTexture(g_dAffinetransPanGL); 7561e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 7571e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gCurrentFBOIndex = 1 - gCurrentFBOIndex; 7581e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 759eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 760eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7610f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( 76241a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jboolean flag) 763eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 76441a2e9735136f372de95652d0828600282c8e967mbansal // TODO: Review this logic 76541a2e9735136f372de95652d0828600282c8e967mbansal if(gWarpImage != (bool) flag) //switching from viewfinder to capture or vice-versa 76641a2e9735136f372de95652d0828600282c8e967mbansal { 767a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Clear gBuffer[0] 768a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetupGraphics(&gBuffer[0]); 769a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 770a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Clear gBuffer[1] 771a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetupGraphics(&gBuffer[1]); 7721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 77341a2e9735136f372de95652d0828600282c8e967mbansal // Clear the screen to black. 774a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.Clear(0.0, 0.0, 0.0, 1.0); 775a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 776a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gLastTx = 0.0f; 777a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanOffset = 0.0f; 778a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanViewfinder = true; 779a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 780a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gThisH1t); 781a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gLastH1t); 78241a2e9735136f372de95652d0828600282c8e967mbansal } 783a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 78441a2e9735136f372de95652d0828600282c8e967mbansal gWarpImage = (bool)flag; 785eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 786eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 787eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7884fabf52f7e8b2419749f5cdc03925d5f8b1c0199Angus KongJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_updateMatrix( 789eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 790eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 791eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal for(int i=0; i<16; i++) 792eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 793eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal g_dAffinetransGL[i] = g_dAffinetrans[i]; 794a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal g_dAffinetransPanGL[i] = g_dAffinetransPan[i]; 795a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal g_dTranslationToFBOCenterGL[i] = g_dTranslationToFBOCenter[i]; 796eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 797eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 798