Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: remoting/android/java/src/org/chromium/chromoting/CardboardDesktopRenderer.java

Issue 1305633002: Refactor drawing desktop. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Create a lock for video frame bitmap in CardboardActivityDesktop. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chromoting; 5 package org.chromium.chromoting;
6 6
7 import android.app.Activity; 7 import android.app.Activity;
8 import android.graphics.Bitmap; 8 import android.graphics.Bitmap;
9 import android.graphics.BitmapFactory; 9 import android.graphics.BitmapFactory;
10 import android.graphics.Point;
10 import android.graphics.PointF; 11 import android.graphics.PointF;
11 import android.opengl.GLES20; 12 import android.opengl.GLES20;
12 import android.opengl.Matrix; 13 import android.opengl.Matrix;
13 14
14 import com.google.vrtoolkit.cardboard.CardboardView; 15 import com.google.vrtoolkit.cardboard.CardboardView;
15 import com.google.vrtoolkit.cardboard.Eye; 16 import com.google.vrtoolkit.cardboard.Eye;
16 import com.google.vrtoolkit.cardboard.HeadTransform; 17 import com.google.vrtoolkit.cardboard.HeadTransform;
17 import com.google.vrtoolkit.cardboard.Viewport; 18 import com.google.vrtoolkit.cardboard.Viewport;
18 19
19 import org.chromium.base.Log; 20 import org.chromium.base.Log;
(...skipping 20 matching lines...) Expand all
40 private static final float DESKTOP_POSITION_Y = 0.0f; 41 private static final float DESKTOP_POSITION_Y = 0.0f;
41 private static final float DESKTOP_POSITION_Z = -2.0f; 42 private static final float DESKTOP_POSITION_Z = -2.0f;
42 private static final float HALF_SKYBOX_SIZE = 100.0f; 43 private static final float HALF_SKYBOX_SIZE = 100.0f;
43 private static final float VIEW_POSITION_MIN = -1.0f; 44 private static final float VIEW_POSITION_MIN = -1.0f;
44 private static final float VIEW_POSITION_MAX = 3.0f; 45 private static final float VIEW_POSITION_MAX = 3.0f;
45 46
46 // Allows user to click even when looking outside the desktop 47 // Allows user to click even when looking outside the desktop
47 // but within edge margin. 48 // but within edge margin.
48 private static final float EDGE_MARGIN = 0.1f; 49 private static final float EDGE_MARGIN = 0.1f;
49 50
50 // Fix the desktop height and adjust width accordingly.
51 private static final float HALF_DESKTOP_HEIGHT = 1.0f;
52
53 // Distance to move camera each time. 51 // Distance to move camera each time.
54 private static final float CAMERA_MOTION_STEP = 0.5f; 52 private static final float CAMERA_MOTION_STEP = 0.5f;
55 53
56 private static final FloatBuffer DESKTOP_TEXTURE_COORDINATES = makeFloatBuff er(new float[] {
57 // Texture coordinate data.
58 0.0f, 0.0f,
59 0.0f, 1.0f,
60 1.0f, 0.0f,
61 0.0f, 1.0f,
62 1.0f, 1.0f,
63 1.0f, 0.0f
64 });
65
66 private static final FloatBuffer SKYBOX_POSITION_COORDINATES = makeFloatBuff er(new float[] { 54 private static final FloatBuffer SKYBOX_POSITION_COORDINATES = makeFloatBuff er(new float[] {
67 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (0) Top -left near 55 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (0) Top -left near
68 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (1) Top- right near 56 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (1) Top- right near
69 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (2) Bot tom-left near 57 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (2) Bot tom-left near
70 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (3) Bott om-right near 58 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, // (3) Bott om-right near
71 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (4) Top -left far 59 -HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (4) Top -left far
72 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (5) Top- right far 60 HALF_SKYBOX_SIZE, HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (5) Top- right far
73 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (6) Bot tom-left far 61 -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, // (6) Bot tom-left far
74 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE // (7) Botto m-right far 62 HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE, -HALF_SKYBOX_SIZE // (7) Botto m-right far
75 }); 63 });
(...skipping 17 matching lines...) Expand all
93 81
94 // Top 82 // Top
95 5, 1, 4, 83 5, 1, 4,
96 4, 1, 0, 84 4, 1, 0,
97 85
98 // Bottom 86 // Bottom
99 6, 2, 7, 87 6, 2, 7,
100 7, 2, 3 88 7, 2, 3
101 }); 89 });
102 90
103 private static final String DESKTOP_VERTEX_SHADER =
104 "uniform mat4 u_CombinedMatrix;"
105 + "attribute vec4 a_Position;"
106 + "attribute vec2 a_TexCoordinate;"
107 + "varying vec2 v_TexCoordinate;"
108 + "void main() {"
109 + " v_TexCoordinate = a_TexCoordinate;"
110 + " gl_Position = u_CombinedMatrix * a_Position;"
111 + "}";
112
113 private static final String DESKTOP_FRAGMENT_SHADER =
114 "precision highp float;"
115 + "uniform sampler2D u_Texture;"
116 + "varying vec2 v_TexCoordinate;"
117 + "const float borderWidth = 0.002;"
118 + "void main() {"
119 + " if (v_TexCoordinate.x > (1.0 - borderWidth) || v_TexCoordinate. x < borderWidth"
120 + " || v_TexCoordinate.y > (1.0 - borderWidth)"
121 + " || v_TexCoordinate.y < borderWidth) {"
122 + " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);"
123 + " } else {"
124 + " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);"
125 + " }"
126 + "}";
127
128 private static final String SKYBOX_VERTEX_SHADER = 91 private static final String SKYBOX_VERTEX_SHADER =
129 "uniform mat4 u_CombinedMatrix;" 92 "uniform mat4 u_CombinedMatrix;"
130 + "attribute vec3 a_Position;" 93 + "attribute vec3 a_Position;"
131 + "varying vec3 v_Position;" 94 + "varying vec3 v_Position;"
132 + "void main() {" 95 + "void main() {"
133 + " v_Position = a_Position;" 96 + " v_Position = a_Position;"
134 // Make sure to convert from the right-handed coordinate system of t he 97 // Make sure to convert from the right-handed coordinate system of t he
135 // world to the left-handed coordinate system of the cube map, other wise, 98 // world to the left-handed coordinate system of the cube map, other wise,
136 // our cube map will still work but everything will be flipped. 99 // our cube map will still work but everything will be flipped.
137 + " v_Position.z = -v_Position.z;" 100 + " v_Position.z = -v_Position.z;"
(...skipping 20 matching lines...) Expand all
158 "https://dl.google.com/chrome-remote-desktop/android-assets/room_back.pn g", 121 "https://dl.google.com/chrome-remote-desktop/android-assets/room_back.pn g",
159 "https://dl.google.com/chrome-remote-desktop/android-assets/room_front.p ng" 122 "https://dl.google.com/chrome-remote-desktop/android-assets/room_front.p ng"
160 }; 123 };
161 124
162 private static final String[] SKYBOX_IMAGE_NAMES = new String[] { 125 private static final String[] SKYBOX_IMAGE_NAMES = new String[] {
163 "skybox_left", "skybox_right", "skybox_bottom", "skybox_top", "skybox_ba ck", "skybox_front" 126 "skybox_left", "skybox_right", "skybox_bottom", "skybox_top", "skybox_ba ck", "skybox_front"
164 }; 127 };
165 128
166 private final Activity mActivity; 129 private final Activity mActivity;
167 130
168 private float mHalfDesktopWidth;
169 private float mCameraPosition; 131 private float mCameraPosition;
170 132
171 // Lock to allow multithreaded access to mCameraPosition. 133 // Lock to allow multithreaded access to mCameraPosition.
172 private Object mCameraPositionLock = new Object(); 134 private Object mCameraPositionLock = new Object();
173 135
174 private float[] mCameraMatrix; 136 private float[] mCameraMatrix;
175 private float[] mViewMatrix; 137 private float[] mViewMatrix;
176 private float[] mProjectionMatrix; 138 private float[] mProjectionMatrix;
177 139
178 // Make matrix member variable to avoid unnecessary initialization. 140 // Make matrix member variable to avoid unnecessary initialization.
179 private float[] mDesktopModelMatrix; 141 private float[] mDesktopModelMatrix;
180 private float[] mDesktopCombinedMatrix; 142 private float[] mDesktopCombinedMatrix;
181 private float[] mEyePointModelMatrix; 143 private float[] mEyePointModelMatrix;
182 private float[] mEyePointCombinedMatrix; 144 private float[] mEyePointCombinedMatrix;
183 private float[] mSkyboxModelMatrix; 145 private float[] mSkyboxModelMatrix;
184 private float[] mSkyboxCombinedMatrix; 146 private float[] mSkyboxCombinedMatrix;
185 147
186 // Direction that user is looking towards. 148 // Direction that user is looking towards.
187 private float[] mForwardVector; 149 private float[] mForwardVector;
188 150
189 // Eye position in desktop. 151 // Eye position in desktop.
190 private float[] mEyePositionVector; 152 private float[] mEyePositionVector;
191 153
192 private int mDesktopCombinedMatrixHandle;
193 private int mPositionHandle;
194 private int mTextureDataHandle;
195 private int mTextureUniformHandle;
196 private int mTextureCoordinateHandle;
197 private int mProgramHandle;
198 private int mDesktopVertexShaderHandle;
199 private int mDesktopFragmentShaderHandle;
200 private int mSkyboxVertexShaderHandle; 154 private int mSkyboxVertexShaderHandle;
201 private int mSkyboxFragmentShaderHandle; 155 private int mSkyboxFragmentShaderHandle;
202 private int mSkyboxProgramHandle; 156 private int mSkyboxProgramHandle;
203 private int mSkyboxPositionHandle; 157 private int mSkyboxPositionHandle;
204 private int mSkyboxCombinedMatrixHandle; 158 private int mSkyboxCombinedMatrixHandle;
205 private int mSkyboxTextureUnitHandle; 159 private int mSkyboxTextureUnitHandle;
206 private int mSkyboxTextureDataHandle; 160 private int mSkyboxTextureDataHandle;
161 private CardboardActivityDesktop mDesktop;
207 private CardboardActivityEyePoint mEyePoint; 162 private CardboardActivityEyePoint mEyePoint;
208 163
209 // Flag to indicate whether reload the desktop texture or not. 164 // Flag to indicate whether reload the desktop texture or not.
210 private boolean mReloadTexture; 165 private boolean mReloadTexture;
211 166
212 /** Lock to allow multithreaded access to mReloadTexture. */ 167 /** Lock to allow multithreaded access to mReloadTexture. */
213 private Object mReloadTextureLock = new Object(); 168 private Object mReloadTextureLock = new Object();
214 169
215 // Lock for eye position related operations. 170 // Lock for eye position related operations.
216 // This protects access to mEyePositionVector as well as mDesktop{Height/Wid th}Pixels. 171 // This protects access to mEyePositionVector.
217 private Object mEyePositionLock = new Object(); 172 private Object mEyePositionLock = new Object();
218 173
219 private int mDesktopHeightPixels;
220 private int mDesktopWidthPixels;
221
222 private FloatBuffer mDesktopCoordinates;
223
224 // Flag to signal that the skybox images are fully decoded and should be loa ded 174 // Flag to signal that the skybox images are fully decoded and should be loa ded
225 // into the OpenGL textures. 175 // into the OpenGL textures.
226 private boolean mLoadSkyboxImagesTexture; 176 private boolean mLoadSkyboxImagesTexture;
227 177
228 // Lock to allow multithreaded access to mLoadSkyboxImagesTexture. 178 // Lock to allow multithreaded access to mLoadSkyboxImagesTexture.
229 private Object mLoadSkyboxImagesTextureLock = new Object(); 179 private Object mLoadSkyboxImagesTextureLock = new Object();
230 180
231 private ChromotingDownloadManager mDownloadManager; 181 private ChromotingDownloadManager mDownloadManager;
232 182
233 public CardboardDesktopRenderer(Activity activity) { 183 public CardboardDesktopRenderer(Activity activity) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 public void onSurfaceCreated(EGLConfig config) { 228 public void onSurfaceCreated(EGLConfig config) {
279 // Set the background clear color to black. 229 // Set the background clear color to black.
280 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 230 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
281 231
282 // Use culling to remove back faces. 232 // Use culling to remove back faces.
283 GLES20.glEnable(GLES20.GL_CULL_FACE); 233 GLES20.glEnable(GLES20.GL_CULL_FACE);
284 234
285 // Enable depth testing. 235 // Enable depth testing.
286 GLES20.glEnable(GLES20.GL_DEPTH_TEST); 236 GLES20.glEnable(GLES20.GL_DEPTH_TEST);
287 237
288 // Set handles for desktop drawing.
289 mDesktopVertexShaderHandle =
290 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, DESKTOP_VERT EX_SHADER);
291 mDesktopFragmentShaderHandle =
292 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, DESKTOP_FR AGMENT_SHADER);
293 mProgramHandle = ShaderHelper.createAndLinkProgram(mDesktopVertexShaderH andle,
294 mDesktopFragmentShaderHandle, new String[] {"a_Position", "a_Tex Coordinate"});
295 mDesktopCombinedMatrixHandle =
296 GLES20.glGetUniformLocation(mProgramHandle, "u_CombinedMatrix");
297 mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_T exture");
298 mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position ");
299 mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a _TexCoordinate");
300 mTextureDataHandle = TextureHelper.createTextureHandle();
301
302 // Set handlers for skybox drawing. 238 // Set handlers for skybox drawing.
303 GLES20.glEnable(GLES20.GL_TEXTURE_CUBE_MAP); 239 GLES20.glEnable(GLES20.GL_TEXTURE_CUBE_MAP);
304 mSkyboxVertexShaderHandle = 240 mSkyboxVertexShaderHandle =
305 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, SKYBOX_VERTE X_SHADER); 241 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, SKYBOX_VERTE X_SHADER);
306 mSkyboxFragmentShaderHandle = 242 mSkyboxFragmentShaderHandle =
307 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, SKYBOX_FRA GMENT_SHADER); 243 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, SKYBOX_FRA GMENT_SHADER);
308 mSkyboxProgramHandle = ShaderHelper.createAndLinkProgram(mSkyboxVertexSh aderHandle, 244 mSkyboxProgramHandle = ShaderHelper.createAndLinkProgram(mSkyboxVertexSh aderHandle,
309 mSkyboxFragmentShaderHandle, 245 mSkyboxFragmentShaderHandle,
310 new String[] {"a_Position", "u_CombinedMatrix", "u_TextureUnit"} ); 246 new String[] {"a_Position", "u_CombinedMatrix", "u_TextureUnit"} );
311 mSkyboxPositionHandle = 247 mSkyboxPositionHandle =
312 GLES20.glGetAttribLocation(mSkyboxProgramHandle, "a_Position"); 248 GLES20.glGetAttribLocation(mSkyboxProgramHandle, "a_Position");
313 mSkyboxCombinedMatrixHandle = 249 mSkyboxCombinedMatrixHandle =
314 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_CombinedMat rix"); 250 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_CombinedMat rix");
315 mSkyboxTextureUnitHandle = 251 mSkyboxTextureUnitHandle =
316 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_TextureUnit "); 252 GLES20.glGetUniformLocation(mSkyboxProgramHandle, "u_TextureUnit ");
317 mSkyboxTextureDataHandle = TextureHelper.createTextureHandle(); 253 mSkyboxTextureDataHandle = TextureHelper.createTextureHandle();
318 254
255 mDesktop = new CardboardActivityDesktop();
319 mEyePoint = new CardboardActivityEyePoint(); 256 mEyePoint = new CardboardActivityEyePoint();
320 } 257 }
321 258
322 @Override 259 @Override
323 public void onSurfaceChanged(int width, int height) { 260 public void onSurfaceChanged(int width, int height) {
324 } 261 }
325 262
326 @Override 263 @Override
327 public void onNewFrame(HeadTransform headTransform) { 264 public void onNewFrame(HeadTransform headTransform) {
328 // Position the eye at the origin. 265 // Position the eye at the origin.
(...skipping 11 matching lines...) Expand all
340 277
341 // Set our up vector. This is where our head would be pointing were we h olding the camera. 278 // Set our up vector. This is where our head would be pointing were we h olding the camera.
342 float upX = 0.0f; 279 float upX = 0.0f;
343 float upY = 1.0f; 280 float upY = 1.0f;
344 float upZ = 0.0f; 281 float upZ = 0.0f;
345 282
346 Matrix.setLookAtM(mCameraMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, look Z, upX, upY, upZ); 283 Matrix.setLookAtM(mCameraMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, look Z, upX, upY, upZ);
347 284
348 headTransform.getForwardVector(mForwardVector, 0); 285 headTransform.getForwardVector(mForwardVector, 0);
349 getLookingPosition(); 286 getLookingPosition();
350 maybeLoadTexture(mTextureDataHandle); 287 maybeLoadDesktopTexture();
351 maybeLoadCubeMapAndCleanImages(mSkyboxTextureDataHandle); 288 maybeLoadCubeMapAndCleanImages(mSkyboxTextureDataHandle);
352 } 289 }
353 290
354 @Override 291 @Override
355 public void onDrawEye(Eye eye) { 292 public void onDrawEye(Eye eye) {
356 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 293 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
357 294
358 // Apply the eye transformation to the camera. 295 // Apply the eye transformation to the camera.
359 Matrix.multiplyMM(mViewMatrix, 0, eye.getEyeView(), 0, mCameraMatrix, 0) ; 296 Matrix.multiplyMM(mViewMatrix, 0, eye.getEyeView(), 0, mCameraMatrix, 0) ;
360 297
361 mProjectionMatrix = eye.getPerspective(Z_NEAR, Z_FAR); 298 mProjectionMatrix = eye.getPerspective(Z_NEAR, Z_FAR);
362 299
363 drawSkybox(); 300 drawSkybox();
364 drawDesktop(); 301 drawDesktop();
365 drawEyePoint(); 302 drawEyePoint();
366 } 303 }
367 304
368 @Override 305 @Override
369 public void onRendererShutdown() { 306 public void onRendererShutdown() {
370 GLES20.glDeleteShader(mDesktopVertexShaderHandle); 307 mDesktop.cleanup();
371 GLES20.glDeleteShader(mDesktopFragmentShaderHandle);
372 mEyePoint.cleanup(); 308 mEyePoint.cleanup();
373 GLES20.glDeleteShader(mSkyboxVertexShaderHandle); 309 GLES20.glDeleteShader(mSkyboxVertexShaderHandle);
374 GLES20.glDeleteShader(mSkyboxFragmentShaderHandle); 310 GLES20.glDeleteShader(mSkyboxFragmentShaderHandle);
375 GLES20.glDeleteTextures(1, new int[] {mTextureDataHandle}, 0);
376 GLES20.glDeleteTextures(1, new int[] {mSkyboxTextureDataHandle}, 0); 311 GLES20.glDeleteTextures(1, new int[] {mSkyboxTextureDataHandle}, 0);
377 mActivity.runOnUiThread(new Runnable() { 312 mActivity.runOnUiThread(new Runnable() {
378 public void run() { 313 public void run() {
379 mDownloadManager.close(); 314 mDownloadManager.close();
380 } 315 }
381 }); 316 });
382 } 317 }
383 318
384 @Override 319 @Override
385 public void onFinishFrame(Viewport viewport) { 320 public void onFinishFrame(Viewport viewport) {
386 } 321 }
387 322
388 private void drawDesktop() { 323 private void drawDesktop() {
389 GLES20.glUseProgram(mProgramHandle); 324 if (!mDesktop.hasVideoFrame()) {
325 // This can happen if the client is connected, but a complete
326 // video frame has not yet been decoded.
327 return;
328 }
390 329
391 // Translate the desktop model. 330
392 Matrix.setIdentityM(mDesktopModelMatrix, 0); 331 Matrix.setIdentityM(mDesktopModelMatrix, 0);
393 Matrix.translateM(mDesktopModelMatrix, 0, DESKTOP_POSITION_X, 332 Matrix.translateM(mDesktopModelMatrix, 0, DESKTOP_POSITION_X,
394 DESKTOP_POSITION_Y, DESKTOP_POSITION_Z); 333 DESKTOP_POSITION_Y, DESKTOP_POSITION_Z);
395 334
396 // Pass in Model View Matrix and Model View Project Matrix. 335 // Pass in Model View Matrix and Model View Project Matrix.
397 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mViewMatrix, 0, mDesktopMod elMatrix, 0); 336 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mViewMatrix, 0, mDesktopMod elMatrix, 0);
398 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mProjectionMatrix, 337 Matrix.multiplyMM(mDesktopCombinedMatrix, 0, mProjectionMatrix,
399 0, mDesktopCombinedMatrix, 0); 338 0, mDesktopCombinedMatrix, 0);
339 mDesktop.setCombinedMatrix(mDesktopCombinedMatrix);
400 340
401 // Pass in model view project matrix. 341 mDesktop.draw();
402 GLES20.glUniformMatrix4fv(mDesktopCombinedMatrixHandle, 1, false,
403 mDesktopCombinedMatrix, 0);
404
405 if (mDesktopCoordinates == null) {
406 // This can happen if the client is connected, but a complete video frame has not yet
407 // been decoded.
408 return;
409 }
410 // Pass in the desktop position.
411 GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20 .GL_FLOAT, false,
412 0, mDesktopCoordinates);
413 GLES20.glEnableVertexAttribArray(mPositionHandle);
414
415 // Pass in texture coordinate.
416 GLES20.glVertexAttribPointer(mTextureCoordinateHandle, TEXTURE_COORDINAT E_DATA_SIZE,
417 GLES20.GL_FLOAT, false, 0, DESKTOP_TEXTURE_COORDINATES);
418 GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
419
420 // Pass in texture data.
421 GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
422 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
423 GLES20.glUniform1i(mTextureUniformHandle, 0);
424
425 // Draw the desktop.
426 int totalPointNumber = 6;
427 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, totalPointNumber);
428 } 342 }
429 343
430 private void drawEyePoint() { 344 private void drawEyePoint() {
431 if (!isLookingAtDesktop()) { 345 if (!isLookingAtDesktop()) {
432 return; 346 return;
433 } 347 }
434 348
435 float eyePointX = clamp(mEyePositionVector[0], -mHalfDesktopWidth, 349 float eyePointX = clamp(mEyePositionVector[0], -mDesktop.getHalfWidth(),
436 mHalfDesktopWidth); 350 mDesktop.getHalfWidth());
437 float eyePointY = clamp(mEyePositionVector[1], -HALF_DESKTOP_HEIGHT, 351 float eyePointY = clamp(mEyePositionVector[1], -mDesktop.getHalfHeight() ,
438 HALF_DESKTOP_HEIGHT); 352 mDesktop.getHalfHeight());
439 Matrix.setIdentityM(mEyePointModelMatrix, 0); 353 Matrix.setIdentityM(mEyePointModelMatrix, 0);
440 Matrix.translateM(mEyePointModelMatrix, 0, -eyePointX, -eyePointY, 354 Matrix.translateM(mEyePointModelMatrix, 0, -eyePointX, -eyePointY,
441 DESKTOP_POSITION_Z); 355 DESKTOP_POSITION_Z);
442 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mViewMatrix, 0, mEyePointM odelMatrix, 0); 356 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mViewMatrix, 0, mEyePointM odelMatrix, 0);
443 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mProjectionMatrix, 357 Matrix.multiplyMM(mEyePointCombinedMatrix, 0, mProjectionMatrix,
444 0, mEyePointCombinedMatrix, 0); 358 0, mEyePointCombinedMatrix, 0);
445 359
446 mEyePoint.setCombinedMatrix(mEyePointCombinedMatrix); 360 mEyePoint.setCombinedMatrix(mEyePointCombinedMatrix);
447 mEyePoint.draw(); 361 mEyePoint.draw();
448 } 362 }
(...skipping 19 matching lines...) Expand all
468 GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_BYTE, 382 GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_BYTE,
469 SKYBOX_INDICES_BYTE_BUFFER); 383 SKYBOX_INDICES_BYTE_BUFFER);
470 } 384 }
471 385
472 /** 386 /**
473 * Returns coordinates in units of pixels in the desktop bitmap. 387 * Returns coordinates in units of pixels in the desktop bitmap.
474 * This can be called on any thread. 388 * This can be called on any thread.
475 */ 389 */
476 public PointF getMouseCoordinates() { 390 public PointF getMouseCoordinates() {
477 PointF result = new PointF(); 391 PointF result = new PointF();
392 Point shapePixels = mDesktop.getShapePixels();
393 int heightPixels = shapePixels.x;
394 int widthPixels = shapePixels.y;
395
478 synchronized (mEyePositionLock) { 396 synchronized (mEyePositionLock) {
479 // Due to the coordinate direction, we only have to inverse x. 397 // Due to the coordinate direction, we only have to inverse x.
480 result.x = (-mEyePositionVector[0] + mHalfDesktopWidth) 398 result.x = (-mEyePositionVector[0] + mDesktop.getHalfWidth())
481 / (2 * mHalfDesktopWidth) * mDesktopWidthPixels; 399 / (2 * mDesktop.getHalfWidth()) * widthPixels;
482 result.y = (mEyePositionVector[1] + HALF_DESKTOP_HEIGHT) 400 result.y = (mEyePositionVector[1] + mDesktop.getHalfHeight())
483 / (2 * HALF_DESKTOP_HEIGHT) * mDesktopHeightPixels; 401 / (2 * mDesktop.getHalfHeight()) * heightPixels;
484 result.x = clamp(result.x, 0, mDesktopWidthPixels); 402 result.x = clamp(result.x, 0, widthPixels);
485 result.y = clamp(result.y, 0, mDesktopHeightPixels); 403 result.y = clamp(result.y, 0, heightPixels);
486 } 404 }
487 return result; 405 return result;
488 } 406 }
489 407
490 /** 408 /**
491 * Returns the passed in value if it resides within the specified range (inc lusive). If not, 409 * Returns the passed in value if it resides within the specified range (inc lusive). If not,
492 * it will return the closest boundary from the range. The ordering of the boundary values 410 * it will return the closest boundary from the range. The ordering of the boundary values
493 * does not matter. 411 * does not matter.
494 * 412 *
495 * @param value The value to be compared against the range. 413 * @param value The value to be compared against the range.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 } 451 }
534 } 452 }
535 } 453 }
536 454
537 /** 455 /**
538 * Return true if user is looking at the desktop. 456 * Return true if user is looking at the desktop.
539 * This method can be called on any thread. 457 * This method can be called on any thread.
540 */ 458 */
541 public boolean isLookingAtDesktop() { 459 public boolean isLookingAtDesktop() {
542 synchronized (mEyePositionLock) { 460 synchronized (mEyePositionLock) {
543 return Math.abs(mEyePositionVector[0]) <= (mHalfDesktopWidth + EDGE_ MARGIN) 461 return Math.abs(mEyePositionVector[0]) <= (mDesktop.getHalfWidth() + EDGE_MARGIN)
544 && Math.abs(mEyePositionVector[1]) <= (HALF_DESKTOP_HEIGHT + EDG E_MARGIN); 462 && Math.abs(mEyePositionVector[1]) <= (mDesktop.getHalfHeight() + EDGE_MARGIN);
545 } 463 }
546 } 464 }
547 465
548 /** 466 /**
549 * Return true if user is looking at the space to the left of the desktop. 467 * Return true if user is looking at the space to the left of the desktop.
550 * This method can be called on any thread. 468 * This method can be called on any thread.
551 */ 469 */
552 public boolean isLookingLeftOfDesktop() { 470 public boolean isLookingLeftOfDesktop() {
553 synchronized (mEyePositionLock) { 471 synchronized (mEyePositionLock) {
554 return mEyePositionVector[0] >= (mHalfDesktopWidth + EDGE_MARGIN); 472 return mEyePositionVector[0] >= (mDesktop.getHalfWidth() + EDGE_MARG IN);
555 } 473 }
556 } 474 }
557 475
558 /** 476 /**
559 * Return true if user is looking at the space to the right of the desktop. 477 * Return true if user is looking at the space to the right of the desktop.
560 * This method can be called on any thread. 478 * This method can be called on any thread.
561 */ 479 */
562 public boolean isLookingRightOfDesktop() { 480 public boolean isLookingRightOfDesktop() {
563 synchronized (mEyePositionLock) { 481 synchronized (mEyePositionLock) {
564 return mEyePositionVector[0] <= -(mHalfDesktopWidth + EDGE_MARGIN); 482 return mEyePositionVector[0] <= -(mDesktop.getHalfWidth() + EDGE_MAR GIN);
565 } 483 }
566 } 484 }
567 485
568 /** 486 /**
569 * Return true if user is looking at the space above the desktop. 487 * Return true if user is looking at the space above the desktop.
570 * This method can be called on any thread. 488 * This method can be called on any thread.
571 */ 489 */
572 public boolean isLookingAboveDesktop() { 490 public boolean isLookingAboveDesktop() {
573 synchronized (mEyePositionLock) { 491 synchronized (mEyePositionLock) {
574 return mEyePositionVector[1] <= -(HALF_DESKTOP_HEIGHT + EDGE_MARGIN) ; 492 return mEyePositionVector[1] <= -(mDesktop.getHalfHeight() + EDGE_MA RGIN);
575 } 493 }
576 } 494 }
577 495
578 /** 496 /**
579 * Return true if user is looking at the space below the desktop. 497 * Return true if user is looking at the space below the desktop.
580 * This method can be called on any thread. 498 * This method can be called on any thread.
581 */ 499 */
582 public boolean isLookingBelowDesktop() { 500 public boolean isLookingBelowDesktop() {
583 synchronized (mEyePositionLock) { 501 synchronized (mEyePositionLock) {
584 return mEyePositionVector[1] >= (HALF_DESKTOP_HEIGHT + EDGE_MARGIN); 502 return mEyePositionVector[1] >= (mDesktop.getHalfHeight() + EDGE_MAR GIN);
585 } 503 }
586 } 504 }
587 505
588 /** 506 /**
589 * Get position on desktop where user is looking at. 507 * Get position on desktop where user is looking at.
590 */ 508 */
591 private void getLookingPosition() { 509 private void getLookingPosition() {
592 synchronized (mEyePositionLock) { 510 synchronized (mEyePositionLock) {
593 if (Math.abs(mForwardVector[2]) < 0.00001f) { 511 if (Math.abs(mForwardVector[2]) < 0.00001f) {
594 mEyePositionVector[0] = Math.signum(mForwardVector[0]) * Float.M AX_VALUE; 512 mEyePositionVector[0] = Math.signum(mForwardVector[0]) * Float.M AX_VALUE;
595 mEyePositionVector[1] = Math.signum(mForwardVector[1]) * Float.M AX_VALUE; 513 mEyePositionVector[1] = Math.signum(mForwardVector[1]) * Float.M AX_VALUE;
596 } else { 514 } else {
597 mEyePositionVector[0] = mForwardVector[0] * DESKTOP_POSITION_Z / mForwardVector[2]; 515 mEyePositionVector[0] = mForwardVector[0] * DESKTOP_POSITION_Z / mForwardVector[2];
598 mEyePositionVector[1] = mForwardVector[1] * DESKTOP_POSITION_Z / mForwardVector[2]; 516 mEyePositionVector[1] = mForwardVector[1] * DESKTOP_POSITION_Z / mForwardVector[2];
599 } 517 }
600 mEyePositionVector[2] = DESKTOP_POSITION_Z; 518 mEyePositionVector[2] = DESKTOP_POSITION_Z;
601 } 519 }
602 } 520 }
603 521
604 /** 522 /**
605 * Link desktop texture with textureDataHandle if {@link mReloadTexture} is true. 523 * Link desktop texture with {@link CardboardActivityDesktop} if {@link mRel oadTexture} is true.
606 * @param textureDataHandle the handle we want attach texture to 524 * @param textureDataHandle the handle we want attach texture to
607 */ 525 */
608 private void maybeLoadTexture(int textureDataHandle) { 526 private void maybeLoadDesktopTexture() {
609 synchronized (mReloadTextureLock) { 527 synchronized (mReloadTextureLock) {
610 if (!mReloadTexture) { 528 if (!mReloadTexture) {
611 return; 529 return;
612 } 530 }
613 } 531 }
614 532
615 // TODO(shichengfeng): Record the time desktop drawing takes. 533 // TODO(shichengfeng): Record the time desktop drawing takes.
616 Bitmap bitmap = JniInterface.getVideoFrame(); 534 Bitmap bitmap = JniInterface.getVideoFrame();
617 535
618 if (bitmap == null) { 536 if (bitmap == null) {
619 // This can happen if the client is connected, but a complete video frame has not yet 537 // This can happen if the client is connected, but a complete video frame has not yet
620 // been decoded. 538 // been decoded.
621 return; 539 return;
622 } 540 }
623 541
624 synchronized (mEyePositionLock) { 542 mDesktop.updateVideoFrameData(bitmap);
625 mDesktopHeightPixels = bitmap.getHeight();
626 mDesktopWidthPixels = bitmap.getWidth();
627 }
628
629 updateDesktopCoordinatesBuffer(bitmap);
630 TextureHelper.linkTexture(textureDataHandle, bitmap);
631 543
632 synchronized (mReloadTextureLock) { 544 synchronized (mReloadTextureLock) {
633 mReloadTexture = false; 545 mReloadTexture = false;
634 } 546 }
635 } 547 }
636 548
637 /** 549 /**
638 * Convert float array to a FloatBuffer for use in OpenGL calls. 550 * Convert float array to a FloatBuffer for use in OpenGL calls.
639 */ 551 */
640 private static FloatBuffer makeFloatBuffer(float[] data) { 552 public static FloatBuffer makeFloatBuffer(float[] data) {
641 FloatBuffer result = ByteBuffer 553 FloatBuffer result = ByteBuffer
642 .allocateDirect(data.length * BYTE_PER_FLOAT) 554 .allocateDirect(data.length * BYTE_PER_FLOAT)
643 .order(ByteOrder.nativeOrder()).asFloatBuffer(); 555 .order(ByteOrder.nativeOrder()).asFloatBuffer();
644 result.put(data).position(0); 556 result.put(data).position(0);
645 return result; 557 return result;
646 } 558 }
647 559
648 /** 560 /**
649 * Update the desktop coordinates based on the new bitmap. Note here we fix the
650 * height of the desktop and vary width accordingly.
651 */
652 private void updateDesktopCoordinatesBuffer(Bitmap bitmap) {
653 int width = bitmap.getWidth();
654 int height = bitmap.getHeight();
655 float newHalfDesktopWidth = width * HALF_DESKTOP_HEIGHT / height;
656 if (Math.abs(mHalfDesktopWidth - newHalfDesktopWidth) > 0.0001) {
657 mHalfDesktopWidth = newHalfDesktopWidth;
658 mDesktopCoordinates = makeFloatBuffer(new float[] {
659 // Desktop model coordinates.
660 -mHalfDesktopWidth, HALF_DESKTOP_HEIGHT, 0.0f,
661 -mHalfDesktopWidth, -HALF_DESKTOP_HEIGHT, 0.0f,
662 mHalfDesktopWidth, HALF_DESKTOP_HEIGHT, 0.0f,
663 -mHalfDesktopWidth, -HALF_DESKTOP_HEIGHT, 0.0f,
664 mHalfDesktopWidth, -HALF_DESKTOP_HEIGHT, 0.0f,
665 mHalfDesktopWidth, HALF_DESKTOP_HEIGHT, 0.0f
666 });
667 }
668 }
669
670 /**
671 * Decode all skybox images to Bitmap files and return them. 561 * Decode all skybox images to Bitmap files and return them.
672 * Only call this method when we have complete skybox images. 562 * Only call this method when we have complete skybox images.
673 * @throws DecodeFileException if BitmapFactory fails to decode file. 563 * @throws DecodeFileException if BitmapFactory fails to decode file.
674 */ 564 */
675 private Bitmap[] decodeSkyboxImages() throws DecodeFileException { 565 private Bitmap[] decodeSkyboxImages() throws DecodeFileException {
676 Bitmap[] result = new Bitmap[SKYBOX_IMAGE_NAMES.length]; 566 Bitmap[] result = new Bitmap[SKYBOX_IMAGE_NAMES.length];
677 String fileDirectory = mDownloadManager.getDownloadDirectory(); 567 String fileDirectory = mDownloadManager.getDownloadDirectory();
678 for (int i = 0; i < SKYBOX_IMAGE_NAMES.length; i++) { 568 for (int i = 0; i < SKYBOX_IMAGE_NAMES.length; i++) {
679 result[i] = BitmapFactory.decodeFile(fileDirectory + "/" + SKYBOX_IM AGE_NAMES[i]); 569 result[i] = BitmapFactory.decodeFile(fileDirectory + "/" + SKYBOX_IM AGE_NAMES[i]);
680 if (result[i] == null) { 570 if (result[i] == null) {
(...skipping 28 matching lines...) Expand all
709 image.recycle(); 599 image.recycle();
710 } 600 }
711 } 601 }
712 602
713 /** 603 /**
714 * Exception when BitmapFactory fails to decode file. 604 * Exception when BitmapFactory fails to decode file.
715 */ 605 */
716 private static class DecodeFileException extends Exception { 606 private static class DecodeFileException extends Exception {
717 } 607 }
718 } 608 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698