mosaic_renderer_jni.cpp revision 41a2e9735136f372de95652d0828600282c8e967
1eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// OpenGL ES 2.0 code
2eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <jni.h>
3eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <android/log.h>
4eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
5eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <db_utilities_camera.h>
6eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic/ImageUtils.h"
7eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer/FrameBuffer.h"
8eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer/WarpRenderer.h"
941a2e9735136f372de95652d0828600282c8e967mbansal#include "mosaic_renderer/SurfaceTextureRenderer.h"
10eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <stdio.h>
11eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <stdlib.h>
12eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <math.h>
13eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
14eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "mosaic_renderer_jni.h"
15eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
16eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#define  LOG_TAG    "MosaicRenderer"
17eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
1841a2e9735136f372de95652d0828600282c8e967mbansal#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)
19eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
20eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
21eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Texture handle
2241a2e9735136f372de95652d0828600282c8e967mbansalGLuint gSurfaceTextureID[1];
23eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
2441a2e9735136f372de95652d0828600282c8e967mbansalbool gWarpImage = true;
25eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
2641a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res input image frame in RGB format for preview rendering and processing
2741a2e9735136f372de95652d0828600282c8e967mbansal// and high-res RGB input image for processing.
2841a2e9735136f372de95652d0828600282c8e967mbansalunsigned char* gPreviewImageRGB[NR];
2941a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res & high-res preview image width
3041a2e9735136f372de95652d0828600282c8e967mbansalint gPreviewImageRGBWidth[NR];
3141a2e9735136f372de95652d0828600282c8e967mbansal// Low-Res & high-res preview image height
3241a2e9735136f372de95652d0828600282c8e967mbansalint gPreviewImageRGBHeight[NR];
33eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
34eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Semaphore to protect simultaneous read/writes from gPreviewImageRGB
35eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalsem_t gPreviewImageRGB_semaphore;
3641a2e9735136f372de95652d0828600282c8e967mbansalsem_t gPreviewImageReady_semaphore;
37eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
38eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen preview FBO width (large enough to store the entire
39eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// preview mosaic).
40eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint gPreviewFBOWidth;
41eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen preview FBO height (large enough to store the entire
42eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// preview mosaic).
43eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalint gPreviewFBOHeight;
44eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
4541a2e9735136f372de95652d0828600282c8e967mbansal// Shader to copy input SurfaceTexture into and RGBA FBO. The two shaders
4641a2e9735136f372de95652d0828600282c8e967mbansal// render to the textures with dimensions corresponding to the low-res and
4741a2e9735136f372de95652d0828600282c8e967mbansal// high-res image frames.
4841a2e9735136f372de95652d0828600282c8e967mbansalSurfaceTextureRenderer gSurfTexRenderer[NR];
4941a2e9735136f372de95652d0828600282c8e967mbansal// Off-screen FBOs to store the low-res and high-res RGBA copied out from
5041a2e9735136f372de95652d0828600282c8e967mbansal// the SurfaceTexture by the gSurfTexRenderers.
5141a2e9735136f372de95652d0828600282c8e967mbansalFrameBuffer gBufferInput[NR];
52eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Shader to add warped current frame to the preview FBO
53eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalWarpRenderer gWarper;
54eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Shader to warp and render the preview FBO to the screen
55eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalWarpRenderer gPreview;
56eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Off-screen FBO to store the result of gWarper
5741a2e9735136f372de95652d0828600282c8e967mbansalFrameBuffer gBuffer;
58eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
59eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Affine transformation in GL 4x4 format (column-major) to warp the
6041a2e9735136f372de95652d0828600282c8e967mbansal// current frame into the first frame coordinate system.
61eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransGL[16];
62eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
63eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// Affine transformation in GL 4x4 format (column-major) to warp the
6441a2e9735136f372de95652d0828600282c8e967mbansal// preview FBO into the current frame coordinate system.
65eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransInvGL[16];
66eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
67eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// GL 4x4 Identity transformation
68eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLfloat g_dAffinetransIdent[] = {
69eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    1., 0., 0., 0.,
70eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    0., 1., 0., 0.,
71eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    0., 0., 1., 0.,
72eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    0., 0., 0., 1.};
73eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
7441a2e9735136f372de95652d0828600282c8e967mbansalconst int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65;
75eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
76eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalstatic void printGLString(const char *name, GLenum s) {
77eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    const char *v = (const char *) glGetString(s);
78eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    LOGI("GL %s = %s\n", name, v);
79eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
80eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
81eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// @return false if there was an error
82eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool checkGlError(const char* op) {
83eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    GLint error = glGetError();
84eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    if (error != 0) {
85eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        LOGE("after %s() glError (0x%x)\n", op, error);
86eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        return false;
87eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
88eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    return true;
89eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
90eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
9141a2e9735136f372de95652d0828600282c8e967mbansalvoid bindSurfaceTexture(GLuint texId)
92eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
9341a2e9735136f372de95652d0828600282c8e967mbansal    glBindTexture(GL_TEXTURE_EXTERNAL_OES_ENUM, texId);
9441a2e9735136f372de95652d0828600282c8e967mbansal
9541a2e9735136f372de95652d0828600282c8e967mbansal    // Can't do mipmapping with camera source
9641a2e9735136f372de95652d0828600282c8e967mbansal    glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MIN_FILTER,
9741a2e9735136f372de95652d0828600282c8e967mbansal            GL_LINEAR);
9841a2e9735136f372de95652d0828600282c8e967mbansal    glTexParameterf(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_MAG_FILTER,
9941a2e9735136f372de95652d0828600282c8e967mbansal            GL_LINEAR);
10041a2e9735136f372de95652d0828600282c8e967mbansal    // Clamp to edge is the only option
10141a2e9735136f372de95652d0828600282c8e967mbansal    glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_S,
10241a2e9735136f372de95652d0828600282c8e967mbansal            GL_CLAMP_TO_EDGE);
10341a2e9735136f372de95652d0828600282c8e967mbansal    glTexParameteri(GL_TEXTURE_EXTERNAL_OES_ENUM, GL_TEXTURE_WRAP_T,
10441a2e9735136f372de95652d0828600282c8e967mbansal            GL_CLAMP_TO_EDGE);
105eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
106eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
10741a2e9735136f372de95652d0828600282c8e967mbansalvoid ClearPreviewImageRGB(int mID)
108eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
10941a2e9735136f372de95652d0828600282c8e967mbansal    unsigned char* ptr = gPreviewImageRGB[mID];
11041a2e9735136f372de95652d0828600282c8e967mbansal    for(int j = 0, i = 0;
11141a2e9735136f372de95652d0828600282c8e967mbansal            j < gPreviewImageRGBWidth[mID] * gPreviewImageRGBHeight[mID] * 4;
11241a2e9735136f372de95652d0828600282c8e967mbansal            j += 4)
11341a2e9735136f372de95652d0828600282c8e967mbansal    {
11441a2e9735136f372de95652d0828600282c8e967mbansal            ptr[i++] = 0;
11541a2e9735136f372de95652d0828600282c8e967mbansal            ptr[i++] = 0;
11641a2e9735136f372de95652d0828600282c8e967mbansal            ptr[i++] = 0;
11741a2e9735136f372de95652d0828600282c8e967mbansal            ptr[i++] = 255;
11841a2e9735136f372de95652d0828600282c8e967mbansal    }
11941a2e9735136f372de95652d0828600282c8e967mbansal
120eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
121eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
122eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid ConvertAffine3x3toGL4x4(double *matGL44, double *mat33)
123eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
124eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[0] = mat33[0];
125eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[1] = mat33[3];
126eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[2] = 0.0;
127eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[3] = mat33[6];
128eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
129eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[4] = mat33[1];
130eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[5] = mat33[4];
131eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[6] = 0.0;
132eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[7] = mat33[7];
133eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
134eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[8] = 0;
135eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[9] = 0;
136eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[10] = 1.0;
137eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[11] = 0.0;
138eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
139eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[12] = mat33[2];
140eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[13] = mat33[5];
141eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[14] = 0.0;
142eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    matGL44[15] = mat33[8];
143eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
144eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
145eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// This function computes fills the 4x4 matrices g_dAffinetrans and
146eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// g_dAffinetransInv using the specified 3x3 affine transformation
147eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// between the first captured frame and the current frame. The computed
148eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// g_dAffinetrans is such that it warps the current frame into the
149eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// coordinate system of the first frame. Thus, applying this transformation
150eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// to each successive frame builds up the preview mosaic in the first frame
151eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// coordinate system. Then the computed g_dAffinetransInv is such that it
152eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// warps the computed preview mosaic into the coordinate system of the
153eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// original (as captured) current frame. This has the effect of showing
154eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// the current frame as is (without warping) but warping the rest of the
155eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal// mosaic data to still be in alignment with this frame.
156eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid UpdateWarpTransformation(float *trs)
157eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
158eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    double H[9], Hinv[9], Hp[9], Htemp[9];
159eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    double K[9], Kinv[9];
160eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
16141a2e9735136f372de95652d0828600282c8e967mbansal    int w = gPreviewImageRGBWidth[LR];
16241a2e9735136f372de95652d0828600282c8e967mbansal    int h = gPreviewImageRGBHeight[LR];
163eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
164eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // K is the transformation to map the canonical [-1,1] vertex coordinate
165eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // system to the [0,w] image coordinate system before applying the given
166eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // affine transformation trs.
167eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[0] = w / 2.0;
168eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[1] = 0.0;
169eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[2] = w / 2.0;
170eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[3] = 0.0;
171eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[4] = -h / 2.0;
172eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[5] = h / 2.0;
173eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[6] = 0.0;
174eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[7] = 0.0;
175eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[8] = 1.0;
176eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
177eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Identity3x3(Kinv);
178eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_InvertCalibrationMatrix(Kinv, K);
179eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
180eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    for(int i=0; i<9; i++)
181eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    {
182eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        H[i] = trs[i];
183eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
184eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
185eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // Move the origin such that the frame is centered in the previewFBO
18641a2e9735136f372de95652d0828600282c8e967mbansal    H[2] += (gPreviewFBOWidth / 2 - gPreviewImageRGBWidth[LR] / 2);
18741a2e9735136f372de95652d0828600282c8e967mbansal    H[5] -= (gPreviewFBOHeight / 2 - gPreviewImageRGBHeight[LR] / 2);
188eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
189eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // Hp = inv(K) * H * K
190eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Identity3x3(Htemp);
191eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Multiply3x3_3x3(Htemp, H, K);
192eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Multiply3x3_3x3(Hp, Kinv, Htemp);
193eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
194eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    ConvertAffine3x3toGL4x4(g_dAffinetrans, Hp);
195eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
196eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    ////////////////////////////////////////////////
197eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    ////// Compute g_dAffinetransInv now...   //////
198eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    ////////////////////////////////////////////////
199eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
200eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    w = gPreviewFBOWidth;
201eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    h = gPreviewFBOHeight;
202eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
203eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[0] = w / 2.0;
204eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[1] = 0.0;
205eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[2] = w / 2.0;
206eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[3] = 0.0;
207eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[4] = h / 2.0;
208eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[5] = h / 2.0;
209eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[6] = 0.0;
210eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[7] = 0.0;
211eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    K[8] = 1.0;
212eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
213eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Identity3x3(Kinv);
214eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_InvertCalibrationMatrix(Kinv, K);
215eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
216eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Identity3x3(Hinv);
217eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_InvertAffineTransform(Hinv, H);
218eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
21941a2e9735136f372de95652d0828600282c8e967mbansal    Hinv[2] += (gPreviewFBOWidth / 2 - gPreviewImageRGBWidth[LR] / 2);
22041a2e9735136f372de95652d0828600282c8e967mbansal    Hinv[5] -= (gPreviewFBOHeight / 2 - gPreviewImageRGBHeight[LR] / 2);
221eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
222eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // Hp = inv(K) * Hinv * K
223eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Identity3x3(Htemp);
224eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Multiply3x3_3x3(Htemp, Hinv, K);
225eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    db_Multiply3x3_3x3(Hp, Kinv, Htemp);
226eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
227eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    ConvertAffine3x3toGL4x4(g_dAffinetransInv, Hp);
228eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
229eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
23041a2e9735136f372de95652d0828600282c8e967mbansalvoid AllocateTextureMemory(int widthHR, int heightHR, int widthLR, int heightLR)
231eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
23241a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewImageRGBWidth[HR] = widthHR;
23341a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewImageRGBHeight[HR] = heightHR;
23441a2e9735136f372de95652d0828600282c8e967mbansal
23541a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewImageRGBWidth[LR] = widthLR;
23641a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewImageRGBHeight[LR] = heightLR;
237eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
238eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_init(&gPreviewImageRGB_semaphore, 0, 1);
23941a2e9735136f372de95652d0828600282c8e967mbansal    sem_init(&gPreviewImageReady_semaphore, 0, 1);
240eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
241eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_wait(&gPreviewImageRGB_semaphore);
24241a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewImageRGB[LR] = ImageUtils::allocateImage(gPreviewImageRGBWidth[LR],
24341a2e9735136f372de95652d0828600282c8e967mbansal            gPreviewImageRGBHeight[LR], 4);
24441a2e9735136f372de95652d0828600282c8e967mbansal    ClearPreviewImageRGB(LR);
24541a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewImageRGB[HR] = ImageUtils::allocateImage(gPreviewImageRGBWidth[HR],
24641a2e9735136f372de95652d0828600282c8e967mbansal            gPreviewImageRGBHeight[HR], 4);
24741a2e9735136f372de95652d0828600282c8e967mbansal    ClearPreviewImageRGB(HR);
248eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_post(&gPreviewImageRGB_semaphore);
249eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
25041a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewFBOWidth = PREVIEW_FBO_WIDTH_SCALE * gPreviewImageRGBWidth[LR];
25141a2e9735136f372de95652d0828600282c8e967mbansal    gPreviewFBOHeight = PREVIEW_FBO_HEIGHT_SCALE * gPreviewImageRGBHeight[LR];
252eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
253eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    UpdateWarpTransformation(g_dAffinetransIdent);
254eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
255eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
256eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalvoid FreeTextureMemory()
257eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
258eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_wait(&gPreviewImageRGB_semaphore);
25941a2e9735136f372de95652d0828600282c8e967mbansal    ImageUtils::freeImage(gPreviewImageRGB[LR]);
26041a2e9735136f372de95652d0828600282c8e967mbansal    ImageUtils::freeImage(gPreviewImageRGB[HR]);
261eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_post(&gPreviewImageRGB_semaphore);
262eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
263eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_destroy(&gPreviewImageRGB_semaphore);
26441a2e9735136f372de95652d0828600282c8e967mbansal    sem_destroy(&gPreviewImageReady_semaphore);
265eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
266eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
267eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalextern "C"
268eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
26941a2e9735136f372de95652d0828600282c8e967mbansal    JNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init(
270eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            JNIEnv * env, jobject obj);
271eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset(
272eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            JNIEnv * env, jobject obj,  jint width, jint height);
27341a2e9735136f372de95652d0828600282c8e967mbansal    JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_preprocess(
27441a2e9735136f372de95652d0828600282c8e967mbansal            JNIEnv * env, jobject obj, jfloatArray stMatrix);
27541a2e9735136f372de95652d0828600282c8e967mbansal    JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_transferGPUtoCPU(
27641a2e9735136f372de95652d0828600282c8e967mbansal            JNIEnv * env, jobject obj);
277eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_step(
278eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            JNIEnv * env, jobject obj);
279eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_ready(
280eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            JNIEnv * env, jobject obj);
28141a2e9735136f372de95652d0828600282c8e967mbansal    JNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_setWarping(
28241a2e9735136f372de95652d0828600282c8e967mbansal            JNIEnv * env, jobject obj, jboolean flag);
283eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal};
284eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
28541a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT jint JNICALL Java_com_android_camera_panorama_MosaicRenderer_init(
286eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        JNIEnv * env, jobject obj)
287eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
28841a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].InitializeGLProgram();
28941a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].InitializeGLProgram();
290eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gWarper.InitializeGLProgram();
291eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gPreview.InitializeGLProgram();
29241a2e9735136f372de95652d0828600282c8e967mbansal    gBuffer.InitializeGLContext();
29341a2e9735136f372de95652d0828600282c8e967mbansal    gBufferInput[LR].InitializeGLContext();
29441a2e9735136f372de95652d0828600282c8e967mbansal    gBufferInput[HR].InitializeGLContext();
295eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
296eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    glBindFramebuffer(GL_FRAMEBUFFER, 0);
29741a2e9735136f372de95652d0828600282c8e967mbansal
29841a2e9735136f372de95652d0828600282c8e967mbansal    glGenTextures(1, gSurfaceTextureID);
29941a2e9735136f372de95652d0828600282c8e967mbansal    // bind the surface texture
30041a2e9735136f372de95652d0828600282c8e967mbansal    bindSurfaceTexture(gSurfaceTextureID[0]);
30141a2e9735136f372de95652d0828600282c8e967mbansal
30241a2e9735136f372de95652d0828600282c8e967mbansal    return (jint) gSurfaceTextureID[0];
303eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
304eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
30541a2e9735136f372de95652d0828600282c8e967mbansal
306eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_reset(
307eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        JNIEnv * env, jobject obj,  jint width, jint height)
308eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
30941a2e9735136f372de95652d0828600282c8e967mbansal    gBuffer.Init(gPreviewFBOWidth, gPreviewFBOHeight, GL_RGBA);
31041a2e9735136f372de95652d0828600282c8e967mbansal
31141a2e9735136f372de95652d0828600282c8e967mbansal    gBufferInput[LR].Init(gPreviewImageRGBWidth[LR],
31241a2e9735136f372de95652d0828600282c8e967mbansal            gPreviewImageRGBHeight[LR], GL_RGBA);
31341a2e9735136f372de95652d0828600282c8e967mbansal
31441a2e9735136f372de95652d0828600282c8e967mbansal    gBufferInput[HR].Init(gPreviewImageRGBWidth[HR],
31541a2e9735136f372de95652d0828600282c8e967mbansal            gPreviewImageRGBHeight[HR], GL_RGBA);
316eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
317eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_wait(&gPreviewImageRGB_semaphore);
31841a2e9735136f372de95652d0828600282c8e967mbansal    ClearPreviewImageRGB(LR);
31941a2e9735136f372de95652d0828600282c8e967mbansal    ClearPreviewImageRGB(HR);
320eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    sem_post(&gPreviewImageRGB_semaphore);
321eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
32241a2e9735136f372de95652d0828600282c8e967mbansal    // bind the surface texture
32341a2e9735136f372de95652d0828600282c8e967mbansal    bindSurfaceTexture(gSurfaceTextureID[0]);
32441a2e9735136f372de95652d0828600282c8e967mbansal
32541a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].SetupGraphics(&gBufferInput[LR]);
32641a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].Clear(0.0, 0.0, 0.0, 1.0);
32741a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].SetViewportMatrix(1, 1, 1, 1);
32841a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].SetScalingMatrix(1.0f, -1.0f);
32941a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].SetInputTextureName(gSurfaceTextureID[0]);
33041a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM);
331eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
33241a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].SetupGraphics(&gBufferInput[HR]);
33341a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].Clear(0.0, 0.0, 0.0, 1.0);
33441a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].SetViewportMatrix(1, 1, 1, 1);
33541a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].SetScalingMatrix(1.0f, -1.0f);
33641a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].SetInputTextureName(gSurfaceTextureID[0]);
33741a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].SetInputTextureType(GL_TEXTURE_EXTERNAL_OES_ENUM);
33841a2e9735136f372de95652d0828600282c8e967mbansal
33941a2e9735136f372de95652d0828600282c8e967mbansal    gWarper.SetupGraphics(&gBuffer);
340eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gWarper.Clear(0.0, 0.0, 0.0, 1.0);
34141a2e9735136f372de95652d0828600282c8e967mbansal    gWarper.SetViewportMatrix(gPreviewImageRGBWidth[LR],
34241a2e9735136f372de95652d0828600282c8e967mbansal            gPreviewImageRGBHeight[LR], gBuffer.GetWidth(),
34341a2e9735136f372de95652d0828600282c8e967mbansal            gBuffer.GetHeight());
344eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gWarper.SetScalingMatrix(1.0f, 1.0f);
34541a2e9735136f372de95652d0828600282c8e967mbansal    gWarper.SetInputTextureName(gBufferInput[LR].GetTextureName());
34641a2e9735136f372de95652d0828600282c8e967mbansal    gWarper.SetInputTextureType(GL_TEXTURE_2D);
347eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
348eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gPreview.SetupGraphics(width, height);
349eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gPreview.Clear(0.0, 0.0, 0.0, 1.0);
350eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gPreview.SetViewportMatrix(1, 1, 1, 1);
351eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gPreview.SetScalingMatrix(1.0f, -1.0f);
35241a2e9735136f372de95652d0828600282c8e967mbansal    gPreview.SetInputTextureName(gBuffer.GetTextureName());
35341a2e9735136f372de95652d0828600282c8e967mbansal    gPreview.SetInputTextureType(GL_TEXTURE_2D);
35441a2e9735136f372de95652d0828600282c8e967mbansal}
35541a2e9735136f372de95652d0828600282c8e967mbansal
35641a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_preprocess(
35741a2e9735136f372de95652d0828600282c8e967mbansal        JNIEnv * env, jobject obj, jfloatArray stMatrix)
35841a2e9735136f372de95652d0828600282c8e967mbansal{
35941a2e9735136f372de95652d0828600282c8e967mbansal    jfloat *stmat = env->GetFloatArrayElements(stMatrix, 0);
36041a2e9735136f372de95652d0828600282c8e967mbansal
36141a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].SetSTMatrix((float*) stmat);
36241a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].SetSTMatrix((float*) stmat);
36341a2e9735136f372de95652d0828600282c8e967mbansal
36441a2e9735136f372de95652d0828600282c8e967mbansal    env->ReleaseFloatArrayElements(stMatrix, stmat, 0);
36541a2e9735136f372de95652d0828600282c8e967mbansal
36641a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[LR].DrawTexture(g_dAffinetransIdent);
36741a2e9735136f372de95652d0828600282c8e967mbansal    gSurfTexRenderer[HR].DrawTexture(g_dAffinetransIdent);
36841a2e9735136f372de95652d0828600282c8e967mbansal}
36941a2e9735136f372de95652d0828600282c8e967mbansal
37041a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_transferGPUtoCPU(
37141a2e9735136f372de95652d0828600282c8e967mbansal        JNIEnv * env, jobject obj)
37241a2e9735136f372de95652d0828600282c8e967mbansal{
37341a2e9735136f372de95652d0828600282c8e967mbansal    sem_wait(&gPreviewImageRGB_semaphore);
37441a2e9735136f372de95652d0828600282c8e967mbansal    // Bind to the input LR FBO and read the Low-Res data from there...
37541a2e9735136f372de95652d0828600282c8e967mbansal    glBindFramebuffer(GL_FRAMEBUFFER, gBufferInput[LR].GetFrameBufferName());
37641a2e9735136f372de95652d0828600282c8e967mbansal    glReadPixels(0,
37741a2e9735136f372de95652d0828600282c8e967mbansal                 0,
37841a2e9735136f372de95652d0828600282c8e967mbansal                 gBufferInput[LR].GetWidth(),
37941a2e9735136f372de95652d0828600282c8e967mbansal                 gBufferInput[LR].GetHeight(),
38041a2e9735136f372de95652d0828600282c8e967mbansal                 GL_RGBA,
38141a2e9735136f372de95652d0828600282c8e967mbansal                 GL_UNSIGNED_BYTE,
38241a2e9735136f372de95652d0828600282c8e967mbansal                 gPreviewImageRGB[LR]);
38341a2e9735136f372de95652d0828600282c8e967mbansal
38441a2e9735136f372de95652d0828600282c8e967mbansal    checkGlError("glReadPixels LR");
38541a2e9735136f372de95652d0828600282c8e967mbansal
38641a2e9735136f372de95652d0828600282c8e967mbansal    // Bind to the input HR FBO and read the high-res data from there...
38741a2e9735136f372de95652d0828600282c8e967mbansal    glBindFramebuffer(GL_FRAMEBUFFER, gBufferInput[HR].GetFrameBufferName());
38841a2e9735136f372de95652d0828600282c8e967mbansal    glReadPixels(0,
38941a2e9735136f372de95652d0828600282c8e967mbansal                 0,
39041a2e9735136f372de95652d0828600282c8e967mbansal                 gBufferInput[HR].GetWidth(),
39141a2e9735136f372de95652d0828600282c8e967mbansal                 gBufferInput[HR].GetHeight(),
39241a2e9735136f372de95652d0828600282c8e967mbansal                 GL_RGBA,
39341a2e9735136f372de95652d0828600282c8e967mbansal                 GL_UNSIGNED_BYTE,
39441a2e9735136f372de95652d0828600282c8e967mbansal                 gPreviewImageRGB[HR]);
39541a2e9735136f372de95652d0828600282c8e967mbansal
39641a2e9735136f372de95652d0828600282c8e967mbansal    checkGlError("glReadPixels HR");
39741a2e9735136f372de95652d0828600282c8e967mbansal
39841a2e9735136f372de95652d0828600282c8e967mbansal    sem_post(&gPreviewImageRGB_semaphore);
399eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
400eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
401eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_step(
402eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        JNIEnv * env, jobject obj)
403eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
404eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // Use the gWarper shader to apply the current frame transformation to the
405eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // current frame and then add it to the gBuffer FBO.
406eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gWarper.DrawTexture(g_dAffinetransGL);
407eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
408eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // Use the gPreview shader to apply the inverse of the current frame
409eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    // transformation to the gBuffer FBO and render it to the screen.
410eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    gPreview.DrawTexture(g_dAffinetransInvGL);
411eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
412eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
41341a2e9735136f372de95652d0828600282c8e967mbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_setWarping(
41441a2e9735136f372de95652d0828600282c8e967mbansal        JNIEnv * env, jobject obj, jboolean flag)
415eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
41641a2e9735136f372de95652d0828600282c8e967mbansal    // TODO: Review this logic
41741a2e9735136f372de95652d0828600282c8e967mbansal    if(gWarpImage != (bool) flag) //switching from viewfinder to capture or vice-versa
41841a2e9735136f372de95652d0828600282c8e967mbansal    {
41941a2e9735136f372de95652d0828600282c8e967mbansal        gWarper.Clear(0.0, 0.0, 0.0, 1.0);
42041a2e9735136f372de95652d0828600282c8e967mbansal        gPreview.Clear(0.0, 0.0, 0.0, 1.0);
42141a2e9735136f372de95652d0828600282c8e967mbansal        // Clear the screen to black.
42241a2e9735136f372de95652d0828600282c8e967mbansal        glBindFramebuffer(GL_FRAMEBUFFER, 0);
42341a2e9735136f372de95652d0828600282c8e967mbansal        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
42441a2e9735136f372de95652d0828600282c8e967mbansal        glClear(GL_COLOR_BUFFER_BIT);
42541a2e9735136f372de95652d0828600282c8e967mbansal    }
42641a2e9735136f372de95652d0828600282c8e967mbansal    gWarpImage = (bool)flag;
427eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
428eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
429eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
430eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalJNIEXPORT void JNICALL Java_com_android_camera_panorama_MosaicRenderer_ready(
431eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        JNIEnv * env, jobject obj)
432eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{
43341a2e9735136f372de95652d0828600282c8e967mbansal    if(!gWarpImage)
434eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    {
43541a2e9735136f372de95652d0828600282c8e967mbansal        // TODO: Review this logic...
43641a2e9735136f372de95652d0828600282c8e967mbansal        UpdateWarpTransformation(g_dAffinetransIdent);
43741a2e9735136f372de95652d0828600282c8e967mbansal
438eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        for(int i=0; i<16; i++)
439eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        {
440eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal            g_dAffinetrans[i] = g_dAffinetransIdent[i];
44141a2e9735136f372de95652d0828600282c8e967mbansal            g_dAffinetransInv[i] = g_dAffinetransIdent[i];
442eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        }
44341a2e9735136f372de95652d0828600282c8e967mbansal        g_dAffinetrans[12] = 1.0f;
44441a2e9735136f372de95652d0828600282c8e967mbansal        g_dAffinetrans[13] = 1.0f;
445eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
446eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal
447eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    for(int i=0; i<16; i++)
448eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    {
449eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        g_dAffinetransGL[i] = g_dAffinetrans[i];
450eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal        g_dAffinetransInvGL[i] = g_dAffinetransInv[i];
451eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal    }
452eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}
453