mosaic_renderer_jni.cpp revision 0f986735d15b2435091bf6e11fc9306c95a5c528
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 176eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// @return false if there was an error 177eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool checkGlError(const char* op) { 178eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal GLint error = glGetError(); 179eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (error != 0) { 180274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen LOGE("after %s() glError (0x%x)", op, error); 181eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return false; 182eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 183eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return true; 184eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 185eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 18641a2e9735136f372de95652d0828600282c8e967mbansalvoid bindSurfaceTexture(GLuint texId) 187eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 18841a2e9735136f372de95652d0828600282c8e967mbansal glBindTexture(GL_TEXTURE_EXTERNAL_OES_ENUM, texId); 18941a2e9735136f372de95652d0828600282c8e967mbansal 19041a2e9735136f372de95652d0828600282c8e967mbansal // Can't do mipmapping with camera source 19141a2e9735136f372de95652d0828600282c8e967mbansal glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MIN_FILTER, 19241a2e9735136f372de95652d0828600282c8e967mbansal GL_LINEAR); 19341a2e9735136f372de95652d0828600282c8e967mbansal glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MAG_FILTER, 19441a2e9735136f372de95652d0828600282c8e967mbansal GL_LINEAR); 19541a2e9735136f372de95652d0828600282c8e967mbansal // Clamp to edge is the only option 19641a2e9735136f372de95652d0828600282c8e967mbansal glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_S, 19741a2e9735136f372de95652d0828600282c8e967mbansal GL_CLAMP_TO_EDGE); 19841a2e9735136f372de95652d0828600282c8e967mbansal glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_T, 19941a2e9735136f372de95652d0828600282c8e967mbansal GL_CLAMP_TO_EDGE); 200eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 201eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 2021e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid ClearPreviewImage(int mID) 203eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 2041e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal unsigned char* ptr = gPreviewImage[mID]; 20541a2e9735136f372de95652d0828600282c8e967mbansal for(int j = 0, i = 0; 2061e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal j < gPreviewImageWidth[mID] * gPreviewImageHeight[mID] * 4; 20741a2e9735136f372de95652d0828600282c8e967mbansal j += 4) 20841a2e9735136f372de95652d0828600282c8e967mbansal { 20941a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 21041a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 21141a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 0; 21241a2e9735136f372de95652d0828600282c8e967mbansal ptr[i++] = 255; 21341a2e9735136f372de95652d0828600282c8e967mbansal } 21441a2e9735136f372de95652d0828600282c8e967mbansal 215eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 216eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 217eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid ConvertAffine3x3toGL4x4(double *matGL44, double *mat33) 218eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 219eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[0] = mat33[0]; 220eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[1] = mat33[3]; 221eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[2] = 0.0; 222eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[3] = mat33[6]; 223eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 224eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[4] = mat33[1]; 225eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[5] = mat33[4]; 226eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[6] = 0.0; 227eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[7] = mat33[7]; 228eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 229eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[8] = 0; 230eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[9] = 0; 231eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[10] = 1.0; 232eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[11] = 0.0; 233eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 234eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[12] = mat33[2]; 235eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[13] = mat33[5]; 236eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[14] = 0.0; 237eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal matGL44[15] = mat33[8]; 238eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 239eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 240d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenbool continuePanningFBO(double panOffset) { 241d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedScreenLimitLeft = -1.0 + VIEWPORT_BORDER_FACTOR_HORZ * 2.0; 242d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedScreenLimitRight = 1.0 - VIEWPORT_BORDER_FACTOR_HORZ * 2.0; 243d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedXPositionOnScreenLeft; 244d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen double normalizedXPositionOnScreenRight; 245d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 246d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Compute the position of the current frame in the screen coordinate system 247d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (gIsLandscapeOrientation) { 248d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenLeft = (2.0 * 249d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen (gCenterOffsetX + panOffset) / gPreviewFBOWidth - 1.0) * 250d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingX; 251d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenRight = (2.0 * 252d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ((gCenterOffsetX + panOffset) + gPreviewImageWidth[HR]) / 253d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreviewFBOWidth - 1.0) * gUILayoutScalingX; 254d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 255d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenLeft = (2.0 * 256d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen (gCenterOffsetX + panOffset) / gPreviewFBOWidth - 1.0) * 257d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingY; 258d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenRight = (2.0 * 259d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ((gCenterOffsetX + panOffset) + gPreviewImageWidth[HR]) / 260d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreviewFBOWidth - 1.0) * gUILayoutScalingY; 261d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 262d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 263d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Stop the viewfinder panning if we hit the maximum border allowed for 264d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // this UI layout 265d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (normalizedXPositionOnScreenRight > normalizedScreenLimitRight || 266d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen normalizedXPositionOnScreenLeft < normalizedScreenLimitLeft) { 267d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen return false; 268d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 269d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen return true; 270d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 271d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen} 272d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 2731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// This function computes fills the 4x4 matrices g_dAffinetrans, 274a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// and g_dAffinetransPan using the specified 3x3 affine 2751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// transformation between the first captured frame and the current frame. 276a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// The computed g_dAffinetrans is such that it warps the preview mosaic in 277a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// the last frame's coordinate system into the coordinate system of the 278a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// current frame. Thus, applying this transformation will create the current 279a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// frame mosaic but with the current frame missing. This frame will then be 280a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// pasted in by gWarper2 after translating it by g_dTranslationToFBOCenter. 281a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// The computed g_dAffinetransPan is such that it offsets the computed preview 282a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal// mosaic horizontally to make the viewfinder pan within the UI layout. 283eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid UpdateWarpTransformation(float *trs) 284eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 285a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal double H[9], Hp[9], Htemp1[9], Htemp2[9], T[9]; 286eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 287a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal for(int i = 0; i < 9; i++) 288eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 289a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gThisH1t[i] = trs[i]; 290eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 291eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 29247f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Alignment is done based on low-res data. 29347f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // To render the preview mosaic, the translation of the high-res mosaic is estimated to 29447f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // H2L_FACTOR x low-res-based tranlation. 29547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gThisH1t[2] *= H2L_FACTOR; 29647f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gThisH1t[5] *= H2L_FACTOR; 29747f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen 298a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(T); 299a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[2] = -gCenterOffsetX; 300a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[5] = -gCenterOffsetY; 301a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 302a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // H = ( inv(gThisH1t) * gLastH1t ) * T 303a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp1); 304a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp2); 305a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(H); 306a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_InvertAffineTransform(Htemp1, gThisH1t); 307a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Htemp2, Htemp1, gLastH1t); 308a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(H, Htemp2, T); 309a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 310a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal for(int i = 0; i < 9; i++) 311a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal { 312a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gLastH1t[i] = gThisH1t[i]; 313a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal } 3141e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 315eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Move the origin such that the frame is centered in the previewFBO 316a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // i.e. H = inv(T) * H 317a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal H[2] += gCenterOffsetX; 318a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal H[5] += gCenterOffsetY; 319eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 32047f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Hp = inv(Km) * H * Km 32147f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Km moves the coordinate system from openGL to image pixels so 3221e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // that the alignment transform H can be applied to them. 32347f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // inv(Km) moves the coordinate system back to openGL normalized 3241e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // coordinates so that the shader can correctly render it. 325a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp1); 326a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Htemp1, H, gKm); 327a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Hp, gKminv, Htemp1); 328eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 329eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal ConvertAffine3x3toGL4x4(g_dAffinetrans, Hp); 330eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 331a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal //////////////////////////////////////////////// 332a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////// Compute g_dAffinetransPan now... ////// 333a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal //////////////////////////////////////////////// 334eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 335a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gThisTx = trs[2]; 336eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 337a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal if(gPanViewfinder) 338a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal { 339a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanOffset += (gThisTx - gLastTx) * VIEWFINDER_PAN_FACTOR_HORZ; 340a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal } 3411e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 3421e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gLastTx = gThisTx; 343d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPanViewfinder = continuePanningFBO(gPanOffset); 344eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 345a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(H); 346a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal H[2] = gPanOffset; 3471e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 34847f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // Hp = inv(Km) * H * Km 349a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Htemp1); 350a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Htemp1, H, gKm); 351a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Hp, gKminv, Htemp1); 3521e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 353d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (gIsLandscapeOrientation) { 354d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ConvertAffine3x3toGL4x4(g_dAffinetransPan, Hp); 355d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 356d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // rotate Hp by 90 degress. 357d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen db_Multiply3x3_3x3(Htemp1, gRotation90, Hp); 358d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen ConvertAffine3x3toGL4x4(g_dAffinetransPan, Htemp1); 359d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 360eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 361eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 36241a2e9735136f372de95652d0828600282c8e967mbansalvoid AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR) 363eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 3641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageWidth[HR] = widthHR; 3651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR] = heightHR; 3661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 3671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageWidth[LR] = widthLR; 3681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR] = heightLR; 36941a2e9735136f372de95652d0828600282c8e967mbansal 3701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 3711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[LR] = ImageUtils::allocateImage(gPreviewImageWidth[LR], 3721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR], 4); 3731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ClearPreviewImage(LR); 3741e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[HR] = ImageUtils::allocateImage(gPreviewImageWidth[HR], 3751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR], 4); 3761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ClearPreviewImage(HR); 3771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 378eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 37947f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[HR]; 38047f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[HR]; 381eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 382a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // The origin is such that the current frame will sit with its center 383a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // at the center of the previewFBO 38447f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gCenterOffsetX = (gPreviewFBOWidth / 2 - gPreviewImageWidth[HR] / 2); 38547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gCenterOffsetY = (gPreviewFBOHeight / 2 - gPreviewImageHeight[HR] / 2); 386a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 387a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanOffset = 0.0f; 388a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 389a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gThisH1t); 390a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gLastH1t); 391a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 392a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanViewfinder = true; 393a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 39447f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen int w = gPreviewImageWidth[HR]; 39547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen int h = gPreviewImageHeight[HR]; 396a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 397a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal int wm = gPreviewFBOWidth; 398a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal int hm = gPreviewFBOHeight; 399a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 400a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // K is the transformation to map the canonical [-1,1] vertex coordinate 401a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // system to the [0,w] image coordinate system before applying the given 402a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // affine transformation trs. 403a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[0] = wm / 2.0 - 0.5; 404a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[1] = 0.0; 405a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[2] = wm / 2.0 - 0.5; 406a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[3] = 0.0; 407a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[4] = hm / 2.0 - 0.5; 408a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[5] = hm / 2.0 - 0.5; 409a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[6] = 0.0; 410a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[7] = 0.0; 411a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gKm[8] = 1.0; 412a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 413a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[0] = w / 2.0 - 0.5; 414a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[1] = 0.0; 415a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[2] = w / 2.0 - 0.5; 416a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[3] = 0.0; 417a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[4] = h / 2.0 - 0.5; 418a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[5] = h / 2.0 - 0.5; 419a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[6] = 0.0; 420a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[7] = 0.0; 421a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gK[8] = 1.0; 422a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 423a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gKinv); 424a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_InvertCalibrationMatrix(gKinv, gK); 425a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 426a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gKminv); 427a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_InvertCalibrationMatrix(gKminv, gKm); 428a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 429a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////////////////////////////////////////// 430a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////// Compute g_Translation now... ////// 431a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ////////////////////////////////////////// 432a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal double T[9], Tp[9], Ttemp[9]; 433a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 434a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(T); 435a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[2] = gCenterOffsetX; 436a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal T[5] = gCenterOffsetY; 437a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 438a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Tp = inv(K) * T * K 439a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(Ttemp); 440a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Ttemp, T, gK); 441a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Multiply3x3_3x3(Tp, gKinv, Ttemp); 442a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 443a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal ConvertAffine3x3toGL4x4(g_dTranslationToFBOCenter, Tp); 444eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 4451e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal UpdateWarpTransformation(g_dIdent3x3); 446eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 447eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 448eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid FreeTextureMemory() 449eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 4501e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 4511e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ImageUtils::freeImage(gPreviewImage[LR]); 4521e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ImageUtils::freeImage(gPreviewImage[HR]); 4531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 454eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 455eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 456eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalextern "C" 457eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 458f93198f838d047572a5cdeaa66668b060985b937Angus Kong JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved); 459f93198f838d047572a5cdeaa66668b060985b937Angus Kong JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved); 4600f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( 461eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 4620f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( 463d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen JNIEnv * env, jobject obj, jint width, jint height, 464d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen jboolean isLandscapeOrientation); 4650f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( 46641a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jfloatArray stMatrix); 4670f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_transferGPUtoCPU( 46841a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj); 4690f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step( 470eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 4710f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_ready( 472eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj); 4730f986735d15b2435091bf6e11fc9306c95a5c528Pin Ting JNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( 47441a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jboolean flag); 475eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}; 476eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 477f93198f838d047572a5cdeaa66668b060985b937Angus Kong 478f93198f838d047572a5cdeaa66668b060985b937Angus KongJNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) 479f93198f838d047572a5cdeaa66668b060985b937Angus Kong{ 480f93198f838d047572a5cdeaa66668b060985b937Angus Kong sem_init(&gPreviewImage_semaphore, 0, 1); 481f93198f838d047572a5cdeaa66668b060985b937Angus Kong 482f93198f838d047572a5cdeaa66668b060985b937Angus Kong return JNI_VERSION_1_4; 483f93198f838d047572a5cdeaa66668b060985b937Angus Kong} 484f93198f838d047572a5cdeaa66668b060985b937Angus Kong 485f93198f838d047572a5cdeaa66668b060985b937Angus Kong 486f93198f838d047572a5cdeaa66668b060985b937Angus KongJNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) 487f93198f838d047572a5cdeaa66668b060985b937Angus Kong{ 488f93198f838d047572a5cdeaa66668b060985b937Angus Kong sem_destroy(&gPreviewImage_semaphore); 489f93198f838d047572a5cdeaa66668b060985b937Angus Kong} 4900f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT jint JNICALL Java_com_android_camera_MosaicRenderer_init( 491eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 492eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 49341a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].InitializeGLProgram(); 49441a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].InitializeGLProgram(); 4951e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].InitializeGLProgram(); 4961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].InitializeGLProgram(); 4971e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.InitializeGLProgram(); 4981e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.InitializeGLProgram(); 499eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.InitializeGLProgram(); 5001e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[0].InitializeGLContext(); 5011e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[1].InitializeGLContext(); 50241a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].InitializeGLContext(); 50341a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].InitializeGLContext(); 5041e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[LR].InitializeGLContext(); 5051e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[HR].InitializeGLContext(); 506eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 507eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glBindFramebuffer(GL_FRAMEBUFFER, 0); 50841a2e9735136f372de95652d0828600282c8e967mbansal 50941a2e9735136f372de95652d0828600282c8e967mbansal glGenTextures(1, gSurfaceTextureID); 51041a2e9735136f372de95652d0828600282c8e967mbansal // bind the surface texture 51141a2e9735136f372de95652d0828600282c8e967mbansal bindSurfaceTexture(gSurfaceTextureID[0]); 51241a2e9735136f372de95652d0828600282c8e967mbansal 51341a2e9735136f372de95652d0828600282c8e967mbansal return (jint) gSurfaceTextureID[0]; 514eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 515eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 51641a2e9735136f372de95652d0828600282c8e967mbansal 517d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chenvoid calculateUILayoutScaling(int width, int height, bool isLandscape) { 518d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (isLandscape) { 519d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // __________ ______ 520d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // |__________| => |______| 521d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // (Preview FBO) (View) 522d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // 523d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Scale the preview FBO's height to the height of view and 524d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // maintain the aspect ratio of the current frame on the screen. 525d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingY = PREVIEW_FBO_HEIGHT_SCALE; 526d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 527d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Note that OpenGL scales a texture to view's width and height automatically. 528d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // The "width / height" inverts the scaling, so as to maintain the aspect ratio 529d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // of the current frame. 530d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingX = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]) 531d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE) 532d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / ((float) width / height); 533d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 534d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // __ 535d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // __________ | | 536d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // |__________| => | | 537d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // (Preview FBO) | | 538d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // |__| 539d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // (View) 540d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Scale the preview FBO's height to the width of view and 541d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // maintain the aspect ratio of the current frame on the screen. 542d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingX = PREVIEW_FBO_HEIGHT_SCALE; 543d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 544d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // Note that OpenGL scales a texture to view's width and height automatically. 545d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // The "height / width" inverts the scaling, so as to maintain the aspect ratio 546d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen // of the current frame. 547d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gUILayoutScalingY = ((float) (PREVIEW_FBO_WIDTH_SCALE * gPreviewImageWidth[LR]) 548d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / (PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageHeight[LR]) * PREVIEW_FBO_HEIGHT_SCALE) 549d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen / ((float) height / width); 550d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 551d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 552d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen} 553d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 5540f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_reset( 555d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen JNIEnv * env, jobject obj, jint width, jint height, jboolean isLandscapeOrientation) 556eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 557d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gIsLandscapeOrientation = isLandscapeOrientation; 558d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen calculateUILayoutScaling(width, height, gIsLandscapeOrientation); 55985dedb803016feea39a78efc4bfc07b4f436cc6cWei-Ta Chen 5601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[0].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); 5611e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBuffer[1].Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA); 5621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 5631e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInput[LR].Init(gPreviewImageWidth[LR], 5641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR], GL_RGBA); 5651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 5661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInput[HR].Init(gPreviewImageWidth[HR], 5671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR], GL_RGBA); 56841a2e9735136f372de95652d0828600282c8e967mbansal 5691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[LR].Init(gPreviewImageWidth[LR], 5701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[LR], GL_RGBA); 57141a2e9735136f372de95652d0828600282c8e967mbansal 5721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gBufferInputYVU[HR].Init(gPreviewImageWidth[HR], 5731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImageHeight[HR], GL_RGBA); 574eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 5751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 5761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ClearPreviewImage(LR); 5771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal ClearPreviewImage(HR); 5781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 579eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 58041a2e9735136f372de95652d0828600282c8e967mbansal // bind the surface texture 58141a2e9735136f372de95652d0828600282c8e967mbansal bindSurfaceTexture(gSurfaceTextureID[0]); 58241a2e9735136f372de95652d0828600282c8e967mbansal 58341a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetupGraphics(&gBufferInput[LR]); 58441a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].Clear(0.0, 0.0, 0.0, 1.0); 58541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetViewportMatrix(1, 1, 1, 1); 58641a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetScalingMatrix(1.0f, -1.0f); 58741a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetInputTextureName(gSurfaceTextureID[0]); 58841a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM); 589eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 59041a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetupGraphics(&gBufferInput[HR]); 59141a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].Clear(0.0, 0.0, 0.0, 1.0); 59241a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetViewportMatrix(1, 1, 1, 1); 59341a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetScalingMatrix(1.0f, -1.0f); 59441a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetInputTextureName(gSurfaceTextureID[0]); 59541a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM); 59641a2e9735136f372de95652d0828600282c8e967mbansal 5971e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].SetupGraphics(&gBufferInputYVU[LR]); 5981e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].Clear(0.0, 0.0, 0.0, 1.0); 5991e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].SetInputTextureName(gBufferInput[LR].GetTextureName()); 6001e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].SetInputTextureType(GL_TEXTURE_2D); 6011e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6021e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].SetupGraphics(&gBufferInputYVU[HR]); 6031e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].Clear(0.0, 0.0, 0.0, 1.0); 6041e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].SetInputTextureName(gBufferInput[HR].GetTextureName()); 6051e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].SetInputTextureType(GL_TEXTURE_2D); 6061e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 607a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // gBuffer[1-gCurrentFBOIndex] --> gWarper1 --> gBuffer[gCurrentFBOIndex] 6081e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 6091e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 610a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetViewportMatrix(1, 1, 1, 1); 6111e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetScalingMatrix(1.0f, 1.0f); 612a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetInputTextureName(gBuffer[1 - gCurrentFBOIndex].GetTextureName()); 6131e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetInputTextureType(GL_TEXTURE_2D); 6141e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 61547f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen // gBufferInput[HR] --> gWarper2 --> gBuffer[gCurrentFBOIndex] 616a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 6171e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.Clear(0.0, 0.0, 0.0, 1.0); 61847f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gWarper2.SetViewportMatrix(gPreviewImageWidth[HR], 61947f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gPreviewImageHeight[HR], gBuffer[gCurrentFBOIndex].GetWidth(), 620a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gBuffer[gCurrentFBOIndex].GetHeight()); 6211e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.SetScalingMatrix(1.0f, 1.0f); 62247f3bff0df080af493ddae1857b82370b592e2f7Wei-Ta Chen gWarper2.SetInputTextureName(gBufferInput[HR].GetTextureName()); 6231e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper2.SetInputTextureType(GL_TEXTURE_2D); 624eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 625eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetupGraphics(width, height); 626eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.Clear(0.0, 0.0, 0.0, 1.0); 627eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal gPreview.SetViewportMatrix(1, 1, 1, 1); 628d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 6291e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // Scale the previewFBO so that the viewfinder window fills the layout height 6301e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal // while maintaining the image aspect ratio 631a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.SetScalingMatrix(gUILayoutScalingX, -1.0f * gUILayoutScalingY); 632a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); 63341a2e9735136f372de95652d0828600282c8e967mbansal gPreview.SetInputTextureType(GL_TEXTURE_2D); 63441a2e9735136f372de95652d0828600282c8e967mbansal} 63541a2e9735136f372de95652d0828600282c8e967mbansal 6360f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_preprocess( 63741a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jfloatArray stMatrix) 63841a2e9735136f372de95652d0828600282c8e967mbansal{ 63941a2e9735136f372de95652d0828600282c8e967mbansal jfloat *stmat = env->GetFloatArrayElements(stMatrix, 0); 64041a2e9735136f372de95652d0828600282c8e967mbansal 64141a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[LR].SetSTMatrix((float*) stmat); 64241a2e9735136f372de95652d0828600282c8e967mbansal gSurfTexRenderer[HR].SetSTMatrix((float*) stmat); 64341a2e9735136f372de95652d0828600282c8e967mbansal 64441a2e9735136f372de95652d0828600282c8e967mbansal env->ReleaseFloatArrayElements(stMatrix, stmat, 0); 64541a2e9735136f372de95652d0828600282c8e967mbansal 646d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gSurfTexRenderer[LR].DrawTexture(g_dAffinetransIdentGL); 647d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gSurfTexRenderer[HR].DrawTexture(g_dAffinetransIdentGL); 64841a2e9735136f372de95652d0828600282c8e967mbansal} 64941a2e9735136f372de95652d0828600282c8e967mbansal 6501e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#ifndef now_ms 6511e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#include <time.h> 6521e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalstatic double 6531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalnow_ms(void) 6541e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 6551e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal //struct timespec res; 6561e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal struct timeval res; 6571e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal //clock_gettime(CLOCK_REALTIME, &res); 6581e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gettimeofday(&res, NULL); 6591e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return 1000.0*res.tv_sec + (double)res.tv_usec/1e3; 6601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 6611e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#endif 6621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6631e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6650f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_transferGPUtoCPU( 66641a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj) 66741a2e9735136f372de95652d0828600282c8e967mbansal{ 6681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal double t0, t1, time_c; 6691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[LR].DrawTexture(); 6711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gYVURenderer[HR].DrawTexture(); 6721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 6731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_wait(&gPreviewImage_semaphore); 67441a2e9735136f372de95652d0828600282c8e967mbansal // Bind to the input LR FBO and read the Low-Res data from there... 6751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glBindFramebuffer(GL_FRAMEBUFFER, gBufferInputYVU[LR].GetFrameBufferName()); 6761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal t0 = now_ms(); 67741a2e9735136f372de95652d0828600282c8e967mbansal glReadPixels(0, 67841a2e9735136f372de95652d0828600282c8e967mbansal 0, 67941a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].GetWidth(), 68041a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[LR].GetHeight(), 68141a2e9735136f372de95652d0828600282c8e967mbansal GL_RGBA, 68241a2e9735136f372de95652d0828600282c8e967mbansal GL_UNSIGNED_BYTE, 6831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[LR]); 68441a2e9735136f372de95652d0828600282c8e967mbansal 68541a2e9735136f372de95652d0828600282c8e967mbansal checkGlError("glReadPixels LR"); 68641a2e9735136f372de95652d0828600282c8e967mbansal 68741a2e9735136f372de95652d0828600282c8e967mbansal // Bind to the input HR FBO and read the high-res data from there... 6881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glBindFramebuffer(GL_FRAMEBUFFER, gBufferInputYVU[HR].GetFrameBufferName()); 6891e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal t0 = now_ms(); 69041a2e9735136f372de95652d0828600282c8e967mbansal glReadPixels(0, 69141a2e9735136f372de95652d0828600282c8e967mbansal 0, 69241a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].GetWidth(), 69341a2e9735136f372de95652d0828600282c8e967mbansal gBufferInput[HR].GetHeight(), 69441a2e9735136f372de95652d0828600282c8e967mbansal GL_RGBA, 69541a2e9735136f372de95652d0828600282c8e967mbansal GL_UNSIGNED_BYTE, 6961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreviewImage[HR]); 69741a2e9735136f372de95652d0828600282c8e967mbansal 69841a2e9735136f372de95652d0828600282c8e967mbansal checkGlError("glReadPixels HR"); 69941a2e9735136f372de95652d0828600282c8e967mbansal 7001e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal sem_post(&gPreviewImage_semaphore); 701eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 702eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7030f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_step( 704eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 705eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 706a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal if(!gWarpImage) // ViewFinder 7071e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 708a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 7091e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); 7101e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 711a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); 712d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen 713d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen if (gIsLandscapeOrientation) { 714d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreview.DrawTexture(g_dAffinetransIdentGL); 715d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } else { 716d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen gPreview.DrawTexture(g_dAffinetransRotation90GL); 717d32aa042a7d7fdb52cd8cec571e7c648f837eaffWei-Ta Chen } 7181e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 7191e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal else 7201e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 7211e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 722a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Clear the destination so that we can paint on it afresh 723a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 724a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetInputTextureName( 725a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gBuffer[1 - gCurrentFBOIndex].GetTextureName()); 726a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.SetupGraphics(&gBuffer[gCurrentFBOIndex]); 727a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.SetInputTextureName(gBuffer[gCurrentFBOIndex].GetTextureName()); 728eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7291e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.DrawTexture(g_dAffinetransGL); 730a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper2.DrawTexture(g_dTranslationToFBOCenterGL); 731a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.DrawTexture(g_dAffinetransPanGL); 7321e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 7331e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gCurrentFBOIndex = 1 - gCurrentFBOIndex; 7341e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 735eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 736eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7370f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_setWarping( 73841a2e9735136f372de95652d0828600282c8e967mbansal JNIEnv * env, jobject obj, jboolean flag) 739eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 74041a2e9735136f372de95652d0828600282c8e967mbansal // TODO: Review this logic 74141a2e9735136f372de95652d0828600282c8e967mbansal if(gWarpImage != (bool) flag) //switching from viewfinder to capture or vice-versa 74241a2e9735136f372de95652d0828600282c8e967mbansal { 743a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Clear gBuffer[0] 744a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetupGraphics(&gBuffer[0]); 745a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 746a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal // Clear gBuffer[1] 747a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gWarper1.SetupGraphics(&gBuffer[1]); 7481e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal gWarper1.Clear(0.0, 0.0, 0.0, 1.0); 74941a2e9735136f372de95652d0828600282c8e967mbansal // Clear the screen to black. 750a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPreview.Clear(0.0, 0.0, 0.0, 1.0); 751a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 752a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gLastTx = 0.0f; 753a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanOffset = 0.0f; 754a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal gPanViewfinder = true; 755a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 756a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gThisH1t); 757a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal db_Identity3x3(gLastH1t); 75841a2e9735136f372de95652d0828600282c8e967mbansal } 759a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal 76041a2e9735136f372de95652d0828600282c8e967mbansal gWarpImage = (bool)flag; 761eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 762eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 763eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 7640f986735d15b2435091bf6e11fc9306c95a5c528Pin TingJNIEXPORT void JNICALL Java_com_android_camera_MosaicRenderer_ready( 765eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal JNIEnv * env, jobject obj) 766eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 767eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal for(int i=0; i<16; i++) 768eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 769eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal g_dAffinetransGL[i] = g_dAffinetrans[i]; 770a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal g_dAffinetransPanGL[i] = g_dAffinetransPan[i]; 771a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal g_dTranslationToFBOCenterGL[i] = g_dTranslationToFBOCenter[i]; 772eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 773eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 774