1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.gltrace.state.transforms; 18 19 import com.android.ide.eclipse.gltrace.FileUtils; 20 import com.android.ide.eclipse.gltrace.GLEnum; 21 import com.android.ide.eclipse.gltrace.GLProtoBuf.GLMessage; 22 import com.android.ide.eclipse.gltrace.state.GLState; 23 import com.android.ide.eclipse.gltrace.state.GLStateType; 24 import com.android.ide.eclipse.gltrace.state.IGLProperty; 25 import com.google.common.io.Files; 26 import com.google.protobuf.ByteString; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.util.ArrayList; 31 import java.util.Arrays; 32 import java.util.Collections; 33 import java.util.List; 34 35 public class StateTransformFactory { 36 private static final String TEXTURE_DATA_FILE_PREFIX = "tex"; //$NON-NLS-1$ 37 private static final String TEXTURE_DATA_FILE_SUFFIX = ".dat"; //$NON-NLS-1$ 38 39 /** Construct a list of transformations to be applied for the provided OpenGL call. */ 40 public static List<IStateTransform> getTransformsFor(GLMessage msg) { 41 switch (msg.getFunction()) { 42 case eglCreateContext: 43 return transformsForEglCreateContext(msg); 44 case glBindFramebuffer: 45 return transformsForGlBindFramebuffer(msg); 46 47 // vertex data 48 case glVertexAttribPointer: 49 return transformsForGlVertexAttribPointer(msg); 50 case glVertexAttrib1f: 51 case glVertexAttrib2f: 52 case glVertexAttrib3f: 53 case glVertexAttrib4f: 54 return transformsForGlVertexAttribxf(msg); 55 case glVertexAttrib1fv: 56 case glVertexAttrib2fv: 57 case glVertexAttrib3fv: 58 case glVertexAttrib4fv: 59 return transformsForGlVertexAttribxfv(msg); 60 case glEnableVertexAttribArray: 61 return transformsForGlEnableVertexAttribArray(msg); 62 case glDisableVertexAttribArray: 63 return transformsForGlDisableVertexAttribArray(msg); 64 65 // VBO's 66 case glBindBuffer: 67 return transformsForGlBindBuffer(msg); 68 case glGenBuffers: 69 return transformsForGlGenBuffers(msg); 70 case glDeleteBuffers: 71 return transformsForGlDeleteBuffers(msg); 72 case glBufferData: 73 return transformsForGlBufferData(msg); 74 case glBufferSubData: 75 return transformsForGlBufferSubData(msg); 76 77 // transformation state 78 case glViewport: 79 return transformsForGlViewport(msg); 80 case glDepthRangef: 81 return transformsForGlDepthRangef(msg); 82 83 // rasterization 84 case glLineWidth: 85 return transformsForGlLineWidth(msg); 86 case glCullFace: 87 return transformsForGlCullFace(msg); 88 case glFrontFace: 89 return transformsForGlFrontFace(msg); 90 case glPolygonOffset: 91 return transformsForGlPolygonOffset(msg); 92 93 // pixel operations 94 case glScissor: 95 return transformsForGlScissor(msg); 96 case glStencilFunc: 97 return transformsForGlStencilFunc(msg); 98 case glStencilFuncSeparate: 99 return transformsForGlStencilFuncSeparate(msg); 100 case glStencilOp: 101 return transformsForGlStencilOp(msg); 102 case glStencilOpSeparate: 103 return transformsForGlStencilOpSeparate(msg); 104 case glDepthFunc: 105 return transformsForGlDepthFunc(msg); 106 case glBlendEquation: 107 return transformsForGlBlendEquation(msg); 108 case glBlendEquationSeparate: 109 return transformsForGlBlendEquationSeparate(msg); 110 case glBlendFunc: 111 return transformsForGlBlendFunc(msg); 112 case glBlendFuncSeparate: 113 return transformsForGlBlendFuncSeparate(msg); 114 case glPixelStorei: 115 return transformsForGlPixelStorei(msg); 116 117 // Texture State Transformations 118 case glGenTextures: 119 return transformsForGlGenTextures(msg); 120 case glDeleteTextures: 121 return transformsForGlDeleteTextures(msg); 122 case glActiveTexture: 123 return transformsForGlActiveTexture(msg); 124 case glBindTexture: 125 return transformsForGlBindTexture(msg); 126 case glTexImage2D: 127 return transformsForGlTexImage2D(msg); 128 case glTexSubImage2D: 129 return transformsForGlTexSubImage2D(msg); 130 case glTexParameteri: 131 return transformsForGlTexParameter(msg); 132 133 // Program State Transformations 134 case glCreateProgram: 135 return transformsForGlCreateProgram(msg); 136 case glUseProgram: 137 return transformsForGlUseProgram(msg); 138 case glAttachShader: 139 return transformsForGlAttachShader(msg); 140 case glDetachShader: 141 return transformsForGlDetachShader(msg); 142 case glGetActiveAttrib: 143 return transformsForGlGetActiveAttrib(msg); 144 case glGetActiveUniform: 145 return transformsForGlGetActiveUniform(msg); 146 case glUniform1i: 147 case glUniform2i: 148 case glUniform3i: 149 case glUniform4i: 150 return transformsForGlUniform(msg, false); 151 case glUniform1f: 152 case glUniform2f: 153 case glUniform3f: 154 case glUniform4f: 155 return transformsForGlUniform(msg, true); 156 case glUniform1iv: 157 case glUniform2iv: 158 case glUniform3iv: 159 case glUniform4iv: 160 return transformsForGlUniformv(msg, false); 161 case glUniform1fv: 162 case glUniform2fv: 163 case glUniform3fv: 164 case glUniform4fv: 165 return transformsForGlUniformv(msg, true); 166 case glUniformMatrix2fv: 167 case glUniformMatrix3fv: 168 case glUniformMatrix4fv: 169 return transformsForGlUniformMatrix(msg); 170 171 // Shader State Transformations 172 case glCreateShader: 173 return transformsForGlCreateShader(msg); 174 case glDeleteShader: 175 return transformsForGlDeleteShader(msg); 176 case glShaderSource: 177 return transformsForGlShaderSource(msg); 178 default: 179 return Collections.emptyList(); 180 } 181 } 182 183 private static List<IStateTransform> transformsForGlVertexAttribPointer(GLMessage msg) { 184 int index = msg.getArgs(0).getIntValue(0); 185 186 int size = msg.getArgs(1).getIntValue(0); 187 int type = msg.getArgs(2).getIntValue(0); 188 boolean normalized = msg.getArgs(3).getBoolValue(0); 189 int stride = msg.getArgs(4).getIntValue(0); 190 int pointer = msg.getArgs(5).getIntValue(0); 191 192 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 193 transforms.add(new PropertyChangeTransform( 194 GLPropertyAccessor.makeAccessor(msg.getContextId(), 195 GLStateType.VERTEX_ARRAY_DATA, 196 GLStateType.VERTEX_ATTRIB_ARRAY, 197 Integer.valueOf(index), 198 GLStateType.VERTEX_ATTRIB_ARRAY_SIZE), 199 Integer.valueOf(size))); 200 transforms.add(new PropertyChangeTransform( 201 GLPropertyAccessor.makeAccessor(msg.getContextId(), 202 GLStateType.VERTEX_ARRAY_DATA, 203 GLStateType.VERTEX_ATTRIB_ARRAY, 204 Integer.valueOf(index), 205 GLStateType.VERTEX_ATTRIB_ARRAY_TYPE), 206 GLEnum.valueOf(type))); 207 transforms.add(new PropertyChangeTransform( 208 GLPropertyAccessor.makeAccessor(msg.getContextId(), 209 GLStateType.VERTEX_ARRAY_DATA, 210 GLStateType.VERTEX_ATTRIB_ARRAY, 211 Integer.valueOf(index), 212 GLStateType.VERTEX_ATTRIB_ARRAY_NORMALIZED), 213 Boolean.valueOf(normalized))); 214 transforms.add(new PropertyChangeTransform( 215 GLPropertyAccessor.makeAccessor(msg.getContextId(), 216 GLStateType.VERTEX_ARRAY_DATA, 217 GLStateType.VERTEX_ATTRIB_ARRAY, 218 Integer.valueOf(index), 219 GLStateType.VERTEX_ATTRIB_ARRAY_STRIDE), 220 Integer.valueOf(stride))); 221 transforms.add(new PropertyChangeTransform( 222 GLPropertyAccessor.makeAccessor(msg.getContextId(), 223 GLStateType.VERTEX_ARRAY_DATA, 224 GLStateType.VERTEX_ATTRIB_ARRAY, 225 Integer.valueOf(index), 226 GLStateType.VERTEX_ATTRIB_ARRAY_POINTER), 227 Integer.valueOf(pointer))); 228 return transforms; 229 } 230 231 private static List<IStateTransform> transformsForGlVertexAttrib(int context, 232 int index, float v0, float v1, float v2, float v3) { 233 List<IStateTransform> transforms = new ArrayList<IStateTransform>(4); 234 transforms.add(new PropertyChangeTransform( 235 GLPropertyAccessor.makeAccessor(context, 236 GLStateType.VERTEX_ARRAY_DATA, 237 GLStateType.GENERIC_VERTEX_ATTRIBUTES, 238 Integer.valueOf(index), 239 GLStateType.GENERIC_VERTEX_ATTRIB_V0), 240 Float.valueOf(v0))); 241 transforms.add(new PropertyChangeTransform( 242 GLPropertyAccessor.makeAccessor(context, 243 GLStateType.VERTEX_ARRAY_DATA, 244 GLStateType.GENERIC_VERTEX_ATTRIBUTES, 245 Integer.valueOf(index), 246 GLStateType.GENERIC_VERTEX_ATTRIB_V1), 247 Float.valueOf(v1))); 248 transforms.add(new PropertyChangeTransform( 249 GLPropertyAccessor.makeAccessor(context, 250 GLStateType.VERTEX_ARRAY_DATA, 251 GLStateType.GENERIC_VERTEX_ATTRIBUTES, 252 Integer.valueOf(index), 253 GLStateType.GENERIC_VERTEX_ATTRIB_V2), 254 Float.valueOf(v2))); 255 transforms.add(new PropertyChangeTransform( 256 GLPropertyAccessor.makeAccessor(context, 257 GLStateType.VERTEX_ARRAY_DATA, 258 GLStateType.GENERIC_VERTEX_ATTRIBUTES, 259 Integer.valueOf(index), 260 GLStateType.GENERIC_VERTEX_ATTRIB_V3), 261 Float.valueOf(v3))); 262 return transforms; 263 } 264 265 private static List<IStateTransform> transformsForGlVertexAttribxf(GLMessage msg) { 266 // void glVertexAttrib1f(GLuint index, GLfloat v0); 267 // void glVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1); 268 // void glVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2); 269 // void glVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 270 271 int index = msg.getArgs(0).getIntValue(0); 272 float v0 = msg.getArgs(1).getFloatValue(0); 273 float v1 = msg.getArgsCount() > 2 ? msg.getArgs(2).getFloatValue(0) : 0; 274 float v2 = msg.getArgsCount() > 3 ? msg.getArgs(3).getFloatValue(0) : 0; 275 float v3 = msg.getArgsCount() > 4 ? msg.getArgs(4).getFloatValue(0) : 0; 276 277 return transformsForGlVertexAttrib(msg.getContextId(), index, v0, v1, v2, v3); 278 } 279 280 private static List<IStateTransform> transformsForGlVertexAttribxfv(GLMessage msg) { 281 // void glVertexAttrib1fv(GLuint index, const GLfloat *v); 282 // void glVertexAttrib2fv(GLuint index, const GLfloat *v); 283 // void glVertexAttrib3fv(GLuint index, const GLfloat *v); 284 // void glVertexAttrib4fv(GLuint index, const GLfloat *v); 285 286 int index = msg.getArgs(0).getIntValue(0); 287 float v[] = new float[4]; 288 289 for (int i = 0; i < msg.getArgs(1).getFloatValueList().size(); i++) { 290 v[i] = msg.getArgs(1).getFloatValue(i); 291 } 292 293 return transformsForGlVertexAttrib(msg.getContextId(), index, v[0], v[1], v[2], v[3]); 294 } 295 296 private static List<IStateTransform> transformsForGlEnableVertexAttribArray(GLMessage msg) { 297 // void glEnableVertexAttribArray(GLuint index); 298 // void glDisableVertexAttribArray(GLuint index); 299 300 int index = msg.getArgs(0).getIntValue(0); 301 IStateTransform transform = new PropertyChangeTransform( 302 GLPropertyAccessor.makeAccessor(msg.getContextId(), 303 GLStateType.VERTEX_ARRAY_DATA, 304 GLStateType.VERTEX_ATTRIB_ARRAY, 305 Integer.valueOf(index), 306 GLStateType.VERTEX_ATTRIB_ARRAY_ENABLED), 307 Boolean.TRUE); 308 return Collections.singletonList(transform); 309 } 310 311 private static List<IStateTransform> transformsForGlDisableVertexAttribArray(GLMessage msg) { 312 // void glEnableVertexAttribArray(GLuint index); 313 // void glDisableVertexAttribArray(GLuint index); 314 315 int index = msg.getArgs(0).getIntValue(0); 316 IStateTransform transform = new PropertyChangeTransform( 317 GLPropertyAccessor.makeAccessor(msg.getContextId(), 318 GLStateType.VERTEX_ARRAY_DATA, 319 GLStateType.VERTEX_ATTRIB_ARRAY, 320 Integer.valueOf(index), 321 GLStateType.VERTEX_ATTRIB_ARRAY_ENABLED), 322 Boolean.FALSE); 323 return Collections.singletonList(transform); 324 } 325 326 private static List<IStateTransform> transformsForGlBindBuffer(GLMessage msg) { 327 // void glBindBuffer(GLenum target, GLuint buffer); 328 // target is one of GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER. 329 330 GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 331 int buffer = msg.getArgs(1).getIntValue(0); 332 GLStateType bufferType; 333 334 if (target == GLEnum.GL_ARRAY_BUFFER) { 335 bufferType = GLStateType.ARRAY_BUFFER_BINDING; 336 } else { 337 bufferType = GLStateType.ELEMENT_ARRAY_BUFFER_BINDING; 338 } 339 340 IStateTransform transform = new PropertyChangeTransform( 341 GLPropertyAccessor.makeAccessor(msg.getContextId(), 342 GLStateType.VERTEX_ARRAY_DATA, 343 GLStateType.BUFFER_BINDINGS, 344 bufferType), 345 Integer.valueOf(buffer)); 346 return Collections.singletonList(transform); 347 } 348 349 private static List<IStateTransform> transformsForGlGenBuffers(GLMessage msg) { 350 // void glGenBuffers(GLsizei n, GLuint * buffers); 351 int n = msg.getArgs(0).getIntValue(0); 352 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 353 354 for (int i = 0; i < n; i++) { 355 transforms.add(new SparseArrayElementAddTransform( 356 GLPropertyAccessor.makeAccessor(msg.getContextId(), 357 GLStateType.VERTEX_ARRAY_DATA, 358 GLStateType.VBO), 359 msg.getArgs(1).getIntValue(i))); 360 } 361 362 return transforms; 363 } 364 365 private static List<IStateTransform> transformsForGlDeleteBuffers(GLMessage msg) { 366 // void glDeleteBuffers(GLsizei n, const GLuint * buffers); 367 int n = msg.getArgs(0).getIntValue(0); 368 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 369 370 for (int i = 0; i < n; i++) { 371 transforms.add(new SparseArrayElementRemoveTransform( 372 GLPropertyAccessor.makeAccessor(msg.getContextId(), 373 GLStateType.VERTEX_ARRAY_DATA, 374 GLStateType.VBO), 375 msg.getArgs(1).getIntValue(i))); 376 } 377 378 return transforms; 379 } 380 381 private static List<IStateTransform> transformsForGlBufferData(GLMessage msg) { 382 // void glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); 383 GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 384 int size = msg.getArgs(1).getIntValue(0); 385 byte[] data = null; 386 GLEnum usage = GLEnum.valueOf(msg.getArgs(3).getIntValue(0)); 387 388 if (msg.getArgs(2).getRawBytesList().size() > 0) { 389 data = msg.getArgs(2).getRawBytesList().get(0).toByteArray(); 390 } else { 391 data = new byte[size]; 392 } 393 394 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 395 396 transforms.add(new PropertyChangeTransform( 397 new CurrentVboPropertyAccessor(msg.getContextId(), 398 target, 399 GLStateType.BUFFER_SIZE), 400 Integer.valueOf(size))); 401 transforms.add(new PropertyChangeTransform( 402 new CurrentVboPropertyAccessor(msg.getContextId(), 403 target, 404 GLStateType.BUFFER_DATA), 405 data)); 406 transforms.add(new PropertyChangeTransform( 407 new CurrentVboPropertyAccessor(msg.getContextId(), 408 target, 409 GLStateType.BUFFER_USAGE), 410 usage)); 411 transforms.add(new PropertyChangeTransform( 412 new CurrentVboPropertyAccessor(msg.getContextId(), 413 target, 414 GLStateType.BUFFER_TYPE), 415 target)); 416 return transforms; 417 } 418 419 private static List<IStateTransform> transformsForGlBufferSubData(GLMessage msg) { 420 // void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); 421 GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 422 int offset = msg.getArgs(1).getIntValue(0); 423 byte[] data = msg.getArgs(3).getRawBytesList().get(0).toByteArray(); 424 425 IStateTransform transform = new BufferSubDataTransform( 426 new CurrentVboPropertyAccessor(msg.getContextId(), 427 target, 428 GLStateType.BUFFER_DATA), 429 offset, data); 430 431 return Collections.singletonList(transform); 432 } 433 434 private static List<IStateTransform> transformsForGlBindFramebuffer(GLMessage msg) { 435 // void glBindFramebuffer(GLenum target, GLuint framebuffer); 436 int fb = msg.getArgs(1).getIntValue(0); 437 IStateTransform transform = new PropertyChangeTransform( 438 GLPropertyAccessor.makeAccessor(msg.getContextId(), 439 GLStateType.FRAMEBUFFER_STATE, 440 GLStateType.FRAMEBUFFER_BINDING), 441 fb); 442 return Collections.singletonList(transform); 443 } 444 445 private static List<IStateTransform> transformsForGlLineWidth(GLMessage msg) { 446 // void glLineWidth(GLfloat width); 447 float width = msg.getArgs(0).getFloatValue(0); 448 IStateTransform transform = new PropertyChangeTransform( 449 GLPropertyAccessor.makeAccessor(msg.getContextId(), 450 GLStateType.RASTERIZATION_STATE, 451 GLStateType.LINE_WIDTH), 452 width); 453 return Collections.singletonList(transform); 454 } 455 456 private static List<IStateTransform> transformsForGlCullFace(GLMessage msg) { 457 // void glCullFace(GLenum mode); 458 int mode = msg.getArgs(0).getIntValue(0); 459 IStateTransform transform = new PropertyChangeTransform( 460 GLPropertyAccessor.makeAccessor(msg.getContextId(), 461 GLStateType.RASTERIZATION_STATE, 462 GLStateType.CULL_FACE_MODE), 463 GLEnum.valueOf(mode)); 464 return Collections.singletonList(transform); 465 } 466 467 private static List<IStateTransform> transformsForGlFrontFace(GLMessage msg) { 468 // void glFrontFace(GLenum mode); 469 int mode = msg.getArgs(0).getIntValue(0); 470 IStateTransform transform = new PropertyChangeTransform( 471 GLPropertyAccessor.makeAccessor(msg.getContextId(), 472 GLStateType.RASTERIZATION_STATE, 473 GLStateType.FRONT_FACE), 474 GLEnum.valueOf(mode)); 475 return Collections.singletonList(transform); 476 } 477 478 private static List<IStateTransform> transformsForGlPolygonOffset(GLMessage msg) { 479 // void glPolygonOffset(GLfloat factor, GLfloat units) 480 float factor = msg.getArgs(0).getFloatValue(0); 481 float units = msg.getArgs(1).getFloatValue(0); 482 483 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 484 transforms.add(new PropertyChangeTransform( 485 GLPropertyAccessor.makeAccessor(msg.getContextId(), 486 GLStateType.RASTERIZATION_STATE, 487 GLStateType.POLYGON_OFFSET_FACTOR), 488 Float.valueOf(factor))); 489 transforms.add(new PropertyChangeTransform( 490 GLPropertyAccessor.makeAccessor(msg.getContextId(), 491 GLStateType.RASTERIZATION_STATE, 492 GLStateType.POLYGON_OFFSET_UNITS), 493 Float.valueOf(units))); 494 return transforms; 495 } 496 497 private static List<IStateTransform> transformsForGlScissor(GLMessage msg) { 498 // void glScissor(GLint x, GLint y, GLsizei width, GLsizei height); 499 int x = msg.getArgs(0).getIntValue(0); 500 int y = msg.getArgs(1).getIntValue(0); 501 int w = msg.getArgs(2).getIntValue(0); 502 int h = msg.getArgs(3).getIntValue(0); 503 504 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 505 transforms.add(new PropertyChangeTransform( 506 GLPropertyAccessor.makeAccessor(msg.getContextId(), 507 GLStateType.PIXEL_OPERATIONS, 508 GLStateType.SCISSOR_BOX, 509 GLStateType.SCISSOR_BOX_X), 510 Integer.valueOf(x))); 511 transforms.add(new PropertyChangeTransform( 512 GLPropertyAccessor.makeAccessor(msg.getContextId(), 513 GLStateType.PIXEL_OPERATIONS, 514 GLStateType.SCISSOR_BOX, 515 GLStateType.SCISSOR_BOX_Y), 516 Integer.valueOf(y))); 517 transforms.add(new PropertyChangeTransform( 518 GLPropertyAccessor.makeAccessor(msg.getContextId(), 519 GLStateType.PIXEL_OPERATIONS, 520 GLStateType.SCISSOR_BOX, 521 GLStateType.SCISSOR_BOX_WIDTH), 522 Integer.valueOf(w))); 523 transforms.add(new PropertyChangeTransform( 524 GLPropertyAccessor.makeAccessor(msg.getContextId(), 525 GLStateType.PIXEL_OPERATIONS, 526 GLStateType.SCISSOR_BOX, 527 GLStateType.SCISSOR_BOX_HEIGHT), 528 Integer.valueOf(h))); 529 return transforms; 530 } 531 532 private static List<IStateTransform> transformsForGlStencilFuncFront(int contextId, 533 GLEnum func, int ref, int mask) { 534 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 535 transforms.add(new PropertyChangeTransform( 536 GLPropertyAccessor.makeAccessor(contextId, 537 GLStateType.PIXEL_OPERATIONS, 538 GLStateType.STENCIL, 539 GLStateType.STENCIL_FUNC), 540 func)); 541 transforms.add(new PropertyChangeTransform( 542 GLPropertyAccessor.makeAccessor(contextId, 543 GLStateType.PIXEL_OPERATIONS, 544 GLStateType.STENCIL, 545 GLStateType.STENCIL_REF), 546 Integer.valueOf(ref))); 547 transforms.add(new PropertyChangeTransform( 548 GLPropertyAccessor.makeAccessor(contextId, 549 GLStateType.PIXEL_OPERATIONS, 550 GLStateType.STENCIL, 551 GLStateType.STENCIL_VALUE_MASK), 552 Integer.valueOf(mask))); 553 return transforms; 554 } 555 556 private static List<IStateTransform> transformsForGlStencilFuncBack(int contextId, 557 GLEnum func, int ref, int mask) { 558 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 559 transforms.add(new PropertyChangeTransform( 560 GLPropertyAccessor.makeAccessor(contextId, 561 GLStateType.PIXEL_OPERATIONS, 562 GLStateType.STENCIL, 563 GLStateType.STENCIL_BACK_FUNC), 564 func)); 565 transforms.add(new PropertyChangeTransform( 566 GLPropertyAccessor.makeAccessor(contextId, 567 GLStateType.PIXEL_OPERATIONS, 568 GLStateType.STENCIL, 569 GLStateType.STENCIL_BACK_REF), 570 Integer.valueOf(ref))); 571 transforms.add(new PropertyChangeTransform( 572 GLPropertyAccessor.makeAccessor(contextId, 573 GLStateType.PIXEL_OPERATIONS, 574 GLStateType.STENCIL, 575 GLStateType.STENCIL_BACK_VALUE_MASK), 576 Integer.valueOf(mask))); 577 return transforms; 578 } 579 580 private static List<IStateTransform> transformsForGlStencilFunc(GLMessage msg) { 581 // void glStencilFunc(GLenum func, GLint ref, GLuint mask); 582 GLEnum func = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 583 int ref = msg.getArgs(1).getIntValue(0); 584 int mask = msg.getArgs(2).getIntValue(0); 585 586 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 587 transforms.addAll(transformsForGlStencilFuncFront(msg.getContextId(), func, ref, mask)); 588 transforms.addAll(transformsForGlStencilFuncBack(msg.getContextId(), func, ref, mask)); 589 return transforms; 590 } 591 592 private static List<IStateTransform> transformsForGlStencilFuncSeparate(GLMessage msg) { 593 // void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); 594 GLEnum face = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 595 GLEnum func = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 596 int ref = msg.getArgs(2).getIntValue(0); 597 int mask = msg.getArgs(3).getIntValue(0); 598 599 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 600 if (face == GLEnum.GL_FRONT || face == GLEnum.GL_FRONT_AND_BACK) { 601 transforms.addAll( 602 transformsForGlStencilFuncFront(msg.getContextId(), func, ref, mask)); 603 } 604 if (face == GLEnum.GL_BACK || face == GLEnum.GL_FRONT_AND_BACK) { 605 transforms.addAll( 606 transformsForGlStencilFuncBack(msg.getContextId(), func, ref, mask)); 607 } 608 609 return transforms; 610 } 611 612 private static List<IStateTransform> transformsForGlStencilOpFront(int contextId, 613 GLEnum sfail, GLEnum dpfail, GLEnum dppass) { 614 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 615 transforms.add(new PropertyChangeTransform( 616 GLPropertyAccessor.makeAccessor(contextId, 617 GLStateType.PIXEL_OPERATIONS, 618 GLStateType.STENCIL, 619 GLStateType.STENCIL_FAIL), 620 sfail)); 621 transforms.add(new PropertyChangeTransform( 622 GLPropertyAccessor.makeAccessor(contextId, 623 GLStateType.PIXEL_OPERATIONS, 624 GLStateType.STENCIL, 625 GLStateType.STENCIL_PASS_DEPTH_FAIL), 626 dpfail)); 627 transforms.add(new PropertyChangeTransform( 628 GLPropertyAccessor.makeAccessor(contextId, 629 GLStateType.PIXEL_OPERATIONS, 630 GLStateType.STENCIL, 631 GLStateType.STENCIL_PASS_DEPTH_PASS), 632 dppass)); 633 return transforms; 634 } 635 636 private static List<IStateTransform> transformsForGlStencilOpBack(int contextId, 637 GLEnum sfail, GLEnum dpfail, GLEnum dppass) { 638 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 639 transforms.add(new PropertyChangeTransform( 640 GLPropertyAccessor.makeAccessor(contextId, 641 GLStateType.PIXEL_OPERATIONS, 642 GLStateType.STENCIL, 643 GLStateType.STENCIL_BACK_FAIL), 644 sfail)); 645 transforms.add(new PropertyChangeTransform( 646 GLPropertyAccessor.makeAccessor(contextId, 647 GLStateType.PIXEL_OPERATIONS, 648 GLStateType.STENCIL, 649 GLStateType.STENCIL_BACK_PASS_DEPTH_FAIL), 650 dpfail)); 651 transforms.add(new PropertyChangeTransform( 652 GLPropertyAccessor.makeAccessor(contextId, 653 GLStateType.PIXEL_OPERATIONS, 654 GLStateType.STENCIL, 655 GLStateType.STENCIL_BACK_PASS_DEPTH_PASS), 656 dppass)); 657 return transforms; 658 } 659 660 private static List<IStateTransform> transformsForGlStencilOp(GLMessage msg) { 661 // void glStencilOp(GLenum sfail, GLenum dpfail, GLenum dppass); 662 GLEnum sfail = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 663 GLEnum dpfail = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 664 GLEnum dppass = GLEnum.valueOf(msg.getArgs(2).getIntValue(0)); 665 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 666 transforms.addAll( 667 transformsForGlStencilOpFront(msg.getContextId(), sfail, dpfail, dppass)); 668 transforms.addAll( 669 transformsForGlStencilOpBack(msg.getContextId(), sfail, dpfail, dppass)); 670 return transforms; 671 } 672 673 private static List<IStateTransform> transformsForGlStencilOpSeparate(GLMessage msg) { 674 // void glStencilOp(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); 675 GLEnum face = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 676 GLEnum sfail = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 677 GLEnum dpfail = GLEnum.valueOf(msg.getArgs(2).getIntValue(0)); 678 GLEnum dppass = GLEnum.valueOf(msg.getArgs(3).getIntValue(0)); 679 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 680 681 if (face == GLEnum.GL_FRONT || face == GLEnum.GL_FRONT_AND_BACK) { 682 transforms.addAll( 683 transformsForGlStencilOpFront(msg.getContextId(), sfail, dpfail, dppass)); 684 } 685 686 if (face == GLEnum.GL_BACK || face == GLEnum.GL_FRONT_AND_BACK) { 687 transforms.addAll( 688 transformsForGlStencilOpBack(msg.getContextId(), sfail, dpfail, dppass)); 689 } 690 691 return transforms; 692 } 693 694 private static List<IStateTransform> transformsForGlDepthFunc(GLMessage msg) { 695 // void glDepthFunc(GLenum func); 696 GLEnum func = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 697 698 IStateTransform transform = new PropertyChangeTransform( 699 GLPropertyAccessor.makeAccessor(msg.getContextId(), 700 GLStateType.PIXEL_OPERATIONS, 701 GLStateType.DEPTH_FUNC), 702 func); 703 return Collections.singletonList(transform); 704 } 705 706 private static IStateTransform transformForGlEquationRGB(int contextId, GLEnum mode) { 707 return new PropertyChangeTransform( 708 GLPropertyAccessor.makeAccessor(contextId, 709 GLStateType.PIXEL_OPERATIONS, 710 GLStateType.BLEND, 711 GLStateType.BLEND_EQUATION_RGB), 712 mode); 713 } 714 715 private static IStateTransform transformForGlEquationAlpha(int contextId, GLEnum mode) { 716 return new PropertyChangeTransform( 717 GLPropertyAccessor.makeAccessor(contextId, 718 GLStateType.PIXEL_OPERATIONS, 719 GLStateType.BLEND, 720 GLStateType.BLEND_EQUATION_ALPHA), 721 mode); 722 } 723 724 private static List<IStateTransform> transformsForGlBlendEquationSeparate(GLMessage msg) { 725 // void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); 726 GLEnum rgb = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 727 GLEnum alpha = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 728 729 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 730 transforms.add(transformForGlEquationRGB(msg.getContextId(), rgb)); 731 transforms.add(transformForGlEquationAlpha(msg.getContextId(), alpha)); 732 return transforms; 733 } 734 735 private static List<IStateTransform> transformsForGlBlendEquation(GLMessage msg) { 736 // void glBlendEquation(GLenum mode); 737 GLEnum mode = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 738 739 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 740 transforms.add(transformForGlEquationRGB(msg.getContextId(), mode)); 741 transforms.add(transformForGlEquationAlpha(msg.getContextId(), mode)); 742 return transforms; 743 } 744 745 private static List<IStateTransform> transformsForGlBlendFuncSrcDst(boolean src, 746 int contextId, GLEnum rgb, GLEnum alpha) { 747 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 748 749 GLStateType rgbAccessor = GLStateType.BLEND_DST_RGB; 750 GLStateType alphaAccessor = GLStateType.BLEND_DST_ALPHA; 751 if (src) { 752 rgbAccessor = GLStateType.BLEND_SRC_RGB; 753 alphaAccessor = GLStateType.BLEND_SRC_ALPHA; 754 } 755 756 transforms.add(new PropertyChangeTransform( 757 GLPropertyAccessor.makeAccessor(contextId, 758 GLStateType.PIXEL_OPERATIONS, 759 GLStateType.BLEND, 760 rgbAccessor), 761 rgb)); 762 transforms.add(new PropertyChangeTransform( 763 GLPropertyAccessor.makeAccessor(contextId, 764 GLStateType.PIXEL_OPERATIONS, 765 GLStateType.BLEND, 766 alphaAccessor), 767 alpha)); 768 return transforms; 769 } 770 771 private static List<IStateTransform> transformsForGlBlendFuncSeparate(GLMessage msg) { 772 // void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) 773 GLEnum srcRgb = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 774 GLEnum dstRgb = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 775 GLEnum srcAlpha = GLEnum.valueOf(msg.getArgs(2).getIntValue(0)); 776 GLEnum dstAlpha = GLEnum.valueOf(msg.getArgs(3).getIntValue(0)); 777 778 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 779 transforms.addAll(transformsForGlBlendFuncSrcDst(true, 780 msg.getContextId(), srcRgb, srcAlpha)); 781 transforms.addAll(transformsForGlBlendFuncSrcDst(false, 782 msg.getContextId(), dstRgb, dstAlpha)); 783 return transforms; 784 } 785 786 private static List<IStateTransform> transformsForGlBlendFunc(GLMessage msg) { 787 // void glBlendFunc(GLenum sfactor, GLenum dfactor); 788 GLEnum sfactor = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 789 GLEnum dfactor = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 790 791 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 792 transforms.addAll(transformsForGlBlendFuncSrcDst(true, 793 msg.getContextId(), sfactor, sfactor)); 794 transforms.addAll(transformsForGlBlendFuncSrcDst(false, 795 msg.getContextId(), dfactor, dfactor)); 796 return transforms; 797 } 798 799 private static List<IStateTransform> transformsForGlPixelStorei(GLMessage msg) { 800 // void glPixelStorei(GLenum pname, GLint param); 801 GLEnum pname = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 802 Integer param = Integer.valueOf(msg.getArgs(1).getIntValue(0)); 803 804 IStateTransform transform; 805 if (pname == GLEnum.GL_PACK_ALIGNMENT) { 806 transform = new PropertyChangeTransform( 807 GLPropertyAccessor.makeAccessor(msg.getContextId(), 808 GLStateType.PIXEL_PACKING, 809 GLStateType.PACK_ALIGNMENT), 810 param); 811 } else { 812 transform = new PropertyChangeTransform( 813 GLPropertyAccessor.makeAccessor(msg.getContextId(), 814 GLStateType.PIXEL_PACKING, 815 GLStateType.UNPACK_ALIGNMENT), 816 param); 817 } 818 819 return Collections.singletonList(transform); 820 } 821 822 private static List<IStateTransform> transformsForGlViewport(GLMessage msg) { 823 // void glViewport( GLint x, GLint y, GLsizei width, GLsizei height); 824 int x = msg.getArgs(0).getIntValue(0); 825 int y = msg.getArgs(1).getIntValue(0); 826 int w = msg.getArgs(2).getIntValue(0); 827 int h = msg.getArgs(3).getIntValue(0); 828 829 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 830 transforms.add(new PropertyChangeTransform( 831 GLPropertyAccessor.makeAccessor(msg.getContextId(), 832 GLStateType.TRANSFORMATION_STATE, 833 GLStateType.VIEWPORT, 834 GLStateType.VIEWPORT_X), 835 Integer.valueOf(x))); 836 transforms.add(new PropertyChangeTransform( 837 GLPropertyAccessor.makeAccessor(msg.getContextId(), 838 GLStateType.TRANSFORMATION_STATE, 839 GLStateType.VIEWPORT, 840 GLStateType.VIEWPORT_Y), 841 Integer.valueOf(y))); 842 transforms.add(new PropertyChangeTransform( 843 GLPropertyAccessor.makeAccessor(msg.getContextId(), 844 GLStateType.TRANSFORMATION_STATE, 845 GLStateType.VIEWPORT, 846 GLStateType.VIEWPORT_WIDTH), 847 Integer.valueOf(w))); 848 transforms.add(new PropertyChangeTransform( 849 GLPropertyAccessor.makeAccessor(msg.getContextId(), 850 GLStateType.TRANSFORMATION_STATE, 851 GLStateType.VIEWPORT, 852 GLStateType.VIEWPORT_HEIGHT), 853 Integer.valueOf(h))); 854 return transforms; 855 } 856 857 private static List<IStateTransform> transformsForGlDepthRangef(GLMessage msg) { 858 // void glDepthRangef(GLclampf nearVal, GLclampf farVal); 859 float near = msg.getArgs(0).getFloatValue(0); 860 float far = msg.getArgs(1).getFloatValue(0); 861 862 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 863 transforms.add(new PropertyChangeTransform( 864 GLPropertyAccessor.makeAccessor(msg.getContextId(), 865 GLStateType.TRANSFORMATION_STATE, 866 GLStateType.DEPTH_RANGE, 867 GLStateType.DEPTH_RANGE_NEAR), 868 Float.valueOf(near))); 869 transforms.add(new PropertyChangeTransform( 870 GLPropertyAccessor.makeAccessor(msg.getContextId(), 871 GLStateType.TRANSFORMATION_STATE, 872 GLStateType.DEPTH_RANGE, 873 GLStateType.DEPTH_RANGE_FAR), 874 Float.valueOf(far))); 875 return transforms; 876 } 877 878 private static List<IStateTransform> transformsForGlGenTextures(GLMessage msg) { 879 // void glGenTextures(GLsizei n, GLuint *textures); 880 int n = msg.getArgs(0).getIntValue(0); 881 882 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 883 for (int i = 0; i < n; i++) { 884 int texture = msg.getArgs(1).getIntValue(i); 885 transforms.add(new SparseArrayElementAddTransform( 886 GLPropertyAccessor.makeAccessor(msg.getContextId(), 887 GLStateType.TEXTURE_STATE, 888 GLStateType.TEXTURES), 889 texture)); 890 } 891 892 return transforms; 893 } 894 895 /** 896 * Obtain a list of transforms that will reset any existing texture units 897 * that are bound to provided texture. 898 * @param contextId context to operate on 899 * @param texture texture that should be unbound 900 */ 901 private static List<IStateTransform> transformsToResetBoundTextureUnits(int contextId, 902 int texture) { 903 List<IStateTransform> transforms = new ArrayList<IStateTransform>( 904 GLState.TEXTURE_UNIT_COUNT); 905 906 for (int i = 0; i < GLState.TEXTURE_UNIT_COUNT; i++) { 907 transforms.add(new PropertyChangeTransform( 908 GLPropertyAccessor.makeAccessor(contextId, 909 GLStateType.TEXTURE_STATE, 910 GLStateType.TEXTURE_UNITS, 911 Integer.valueOf(i), 912 GLStateType.TEXTURE_BINDING_2D), 913 Integer.valueOf(0), /* reset binding to texture 0 */ 914 Predicates.matchesInteger(texture) /* only if currently bound to @texture */ )); 915 } 916 return transforms; 917 } 918 919 private static List<IStateTransform> transformsForGlDeleteTextures(GLMessage msg) { 920 // void glDeleteTextures(GLsizei n, const GLuint * textures); 921 int n = msg.getArgs(0).getIntValue(0); 922 923 List<IStateTransform> transforms = new ArrayList<IStateTransform>(n); 924 for (int i = 0; i < n; i++) { 925 int texture = msg.getArgs(1).getIntValue(i); 926 transforms.add(new SparseArrayElementRemoveTransform( 927 GLPropertyAccessor.makeAccessor(msg.getContextId(), 928 GLStateType.TEXTURE_STATE, 929 GLStateType.TEXTURES), 930 texture)); 931 transforms.addAll(transformsToResetBoundTextureUnits(msg.getContextId(), texture)); 932 } 933 934 return transforms; 935 } 936 937 private static List<IStateTransform> transformsForGlActiveTexture(GLMessage msg) { 938 // void glActiveTexture(GLenum texture); 939 GLEnum texture = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 940 Integer textureIndex = Integer.valueOf(texture.value - GLEnum.GL_TEXTURE0.value); 941 IStateTransform transform = new PropertyChangeTransform( 942 GLPropertyAccessor.makeAccessor(msg.getContextId(), 943 GLStateType.TEXTURE_STATE, 944 GLStateType.ACTIVE_TEXTURE_UNIT), 945 textureIndex); 946 return Collections.singletonList(transform); 947 } 948 949 private static GLStateType getTextureUnitTargetName(GLEnum target) { 950 if (target == GLEnum.GL_TEXTURE_CUBE_MAP) { 951 return GLStateType.TEXTURE_BINDING_CUBE_MAP; 952 } else if (target == GLEnum.GL_TEXTURE_EXTERNAL) { 953 // added by OES_EGL_image_external 954 return GLStateType.TEXTURE_BINDING_EXTERNAL; 955 } else { 956 return GLStateType.TEXTURE_BINDING_2D; 957 } 958 } 959 960 private static GLStateType getTextureTargetName(GLEnum pname) { 961 switch (pname) { 962 case GL_TEXTURE_MIN_FILTER: 963 return GLStateType.TEXTURE_MIN_FILTER; 964 case GL_TEXTURE_MAG_FILTER: 965 return GLStateType.TEXTURE_MAG_FILTER; 966 case GL_TEXTURE_WRAP_S: 967 return GLStateType.TEXTURE_WRAP_S; 968 case GL_TEXTURE_WRAP_T: 969 return GLStateType.TEXTURE_WRAP_T; 970 } 971 972 assert false : "glTexParameter's pname argument does not support provided value."; 973 return GLStateType.TEXTURE_MIN_FILTER; 974 } 975 976 private static List<IStateTransform> transformsForGlBindTexture(GLMessage msg) { 977 // void glBindTexture(GLenum target, GLuint texture); 978 GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 979 Integer texture = Integer.valueOf(msg.getArgs(1).getIntValue(0)); 980 981 IStateTransform transform = new PropertyChangeTransform( 982 new TextureUnitPropertyAccessor(msg.getContextId(), 983 getTextureUnitTargetName(target)), 984 texture); 985 return Collections.singletonList(transform); 986 } 987 988 /** 989 * Utility function used by both {@link #transformsForGlTexImage2D(GLMessage) and 990 * {@link #transformsForGlTexSubImage2D(GLMessage)}. 991 */ 992 private static List<IStateTransform> transformsForGlTexImage(GLMessage msg, int widthArgIndex, 993 int heightArgIndex, int xOffsetIndex, int yOffsetIndex) { 994 GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 995 int level = msg.getArgs(1).getIntValue(0); 996 Integer width = Integer.valueOf(msg.getArgs(widthArgIndex).getIntValue(0)); 997 Integer height = Integer.valueOf(msg.getArgs(heightArgIndex).getIntValue(0)); 998 GLEnum format = GLEnum.valueOf(msg.getArgs(6).getIntValue(0)); 999 GLEnum type = GLEnum.valueOf(msg.getArgs(7).getIntValue(0)); 1000 1001 List<IStateTransform> transforms = new ArrayList<IStateTransform>(); 1002 transforms.add(new PropertyChangeTransform( 1003 new TexturePropertyAccessor(msg.getContextId(), 1004 getTextureUnitTargetName(target), 1005 level, 1006 GLStateType.TEXTURE_WIDTH), 1007 width)); 1008 transforms.add(new PropertyChangeTransform( 1009 new TexturePropertyAccessor(msg.getContextId(), 1010 getTextureUnitTargetName(target), 1011 level, 1012 GLStateType.TEXTURE_HEIGHT), 1013 height)); 1014 transforms.add(new PropertyChangeTransform( 1015 new TexturePropertyAccessor(msg.getContextId(), 1016 getTextureUnitTargetName(target), 1017 level, 1018 GLStateType.TEXTURE_FORMAT), 1019 format)); 1020 transforms.add(new PropertyChangeTransform( 1021 new TexturePropertyAccessor(msg.getContextId(), 1022 getTextureUnitTargetName(target), 1023 level, 1024 GLStateType.TEXTURE_IMAGE_TYPE), 1025 type)); 1026 1027 // if texture data is available, extract and store it in the cache folder 1028 File f = null; 1029 if (msg.getArgs(8).getIsArray()) { 1030 ByteString data = msg.getArgs(8).getRawBytes(0); 1031 f = FileUtils.createTempFile(TEXTURE_DATA_FILE_PREFIX, TEXTURE_DATA_FILE_SUFFIX); 1032 try { 1033 Files.write(data.toByteArray(), f); 1034 } catch (IOException e) { 1035 throw new RuntimeException(e); 1036 } 1037 } 1038 1039 int xOffset = 0; 1040 int yOffset = 0; 1041 1042 if (xOffsetIndex >= 0) { 1043 xOffset = msg.getArgs(xOffsetIndex).getIntValue(0); 1044 } 1045 1046 if (yOffsetIndex >= 0) { 1047 yOffset = msg.getArgs(yOffsetIndex).getIntValue(0); 1048 } 1049 1050 transforms.add(new TexImageTransform( 1051 new TexturePropertyAccessor(msg.getContextId(), 1052 getTextureUnitTargetName(target), 1053 level, 1054 GLStateType.TEXTURE_IMAGE), 1055 f, format, type, xOffset, yOffset, width, height)); 1056 1057 return transforms; 1058 } 1059 1060 private static List<IStateTransform> transformsForGlTexImage2D(GLMessage msg) { 1061 // void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, 1062 // GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data); 1063 return transformsForGlTexImage(msg, 3, 4, -1, -1); 1064 } 1065 1066 private static List<IStateTransform> transformsForGlTexSubImage2D(GLMessage msg) { 1067 // void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, 1068 // GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data); 1069 return transformsForGlTexImage(msg, 4, 5, 2, 3); 1070 } 1071 1072 private static List<IStateTransform> transformsForGlTexParameter(GLMessage msg) { 1073 // void glTexParameteri(GLenum target, GLenum pname, GLint param); 1074 GLEnum target = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 1075 GLEnum pname = GLEnum.valueOf(msg.getArgs(1).getIntValue(0)); 1076 GLEnum pvalue = GLEnum.valueOf(msg.getArgs(2).getIntValue(0)); 1077 1078 if (pname != GLEnum.GL_TEXTURE_MIN_FILTER 1079 && pname != GLEnum.GL_TEXTURE_MAG_FILTER 1080 && pname != GLEnum.GL_TEXTURE_WRAP_S 1081 && pname != GLEnum.GL_TEXTURE_WRAP_T) { 1082 throw new IllegalArgumentException( 1083 String.format("Unsupported parameter (%s) for glTexParameter()", pname)); 1084 } 1085 1086 IStateTransform transform = new PropertyChangeTransform( 1087 new TexturePropertyAccessor(msg.getContextId(), 1088 getTextureUnitTargetName(target), 1089 getTextureTargetName(pname)), 1090 pvalue); 1091 return Collections.singletonList(transform); 1092 } 1093 1094 private static List<IStateTransform> transformsForGlCreateProgram(GLMessage msg) { 1095 // GLuint glCreateProgram(void); 1096 int program = msg.getReturnValue().getIntValue(0); 1097 1098 IStateTransform transform = new SparseArrayElementAddTransform( 1099 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1100 GLStateType.PROGRAM_STATE, 1101 GLStateType.PROGRAMS), 1102 program); 1103 return Collections.singletonList(transform); 1104 } 1105 1106 private static List<IStateTransform> transformsForGlUseProgram(GLMessage msg) { 1107 // void glUseProgram(GLuint program); 1108 Integer program = Integer.valueOf(msg.getArgs(0).getIntValue(0)); 1109 1110 IStateTransform transform = new PropertyChangeTransform( 1111 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1112 GLStateType.PROGRAM_STATE, 1113 GLStateType.CURRENT_PROGRAM), 1114 program); 1115 return Collections.singletonList(transform); 1116 } 1117 1118 private static List<IStateTransform> transformsForGlAttachShader(GLMessage msg) { 1119 // void glAttachShader(GLuint program, GLuint shader); 1120 int program = msg.getArgs(0).getIntValue(0); 1121 int shader = msg.getArgs(1).getIntValue(0); 1122 1123 IStateTransform transform = new SparseArrayElementAddTransform( 1124 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1125 GLStateType.PROGRAM_STATE, 1126 GLStateType.PROGRAMS, 1127 Integer.valueOf(program), 1128 GLStateType.ATTACHED_SHADERS), 1129 Integer.valueOf(shader)); 1130 return Collections.singletonList(transform); 1131 } 1132 1133 private static List<IStateTransform> transformsForGlDetachShader(GLMessage msg) { 1134 // void glDetachShader(GLuint program, GLuint shader); 1135 int program = msg.getArgs(0).getIntValue(0); 1136 int shader = msg.getArgs(1).getIntValue(0); 1137 1138 IStateTransform transform = new SparseArrayElementRemoveTransform( 1139 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1140 GLStateType.PROGRAM_STATE, 1141 GLStateType.PROGRAMS, 1142 Integer.valueOf(program), 1143 GLStateType.ATTACHED_SHADERS), 1144 Integer.valueOf(shader)); 1145 return Collections.singletonList(transform); 1146 } 1147 1148 private static List<IStateTransform> transformsForGlGetActiveAttribOrUniform( 1149 GLMessage msg, boolean isAttrib) { 1150 // void glGetActive[Attrib|Uniform](GLuint program, GLuint index, GLsizei bufsize, 1151 // GLsizei* length, GLint* size, GLenum* type, GLchar* name); 1152 int program = msg.getArgs(0).getIntValue(0); 1153 int size = msg.getArgs(4).getIntValue(0); 1154 GLEnum type = GLEnum.valueOf(msg.getArgs(5).getIntValue(0)); 1155 String name = msg.getArgs(6).getCharValue(0).toStringUtf8(); 1156 1157 // The 2nd argument (index) does not give the correct location of the 1158 // attribute/uniform in device. The actual location is obtained from 1159 // the getAttribLocation or getUniformLocation calls. The trace library 1160 // appends this value as an additional last argument to this call. 1161 int location = msg.getArgs(7).getIntValue(0); 1162 1163 GLStateType activeInput; 1164 GLStateType inputName; 1165 GLStateType inputType; 1166 GLStateType inputSize; 1167 1168 if (isAttrib) { 1169 activeInput = GLStateType.ACTIVE_ATTRIBUTES; 1170 inputName = GLStateType.ATTRIBUTE_NAME; 1171 inputType = GLStateType.ATTRIBUTE_TYPE; 1172 inputSize = GLStateType.ATTRIBUTE_SIZE; 1173 } else { 1174 activeInput = GLStateType.ACTIVE_UNIFORMS; 1175 inputName = GLStateType.UNIFORM_NAME; 1176 inputType = GLStateType.UNIFORM_TYPE; 1177 inputSize = GLStateType.UNIFORM_SIZE; 1178 } 1179 1180 IStateTransform addAttribute = new SparseArrayElementAddTransform( 1181 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1182 GLStateType.PROGRAM_STATE, 1183 GLStateType.PROGRAMS, 1184 Integer.valueOf(program), 1185 activeInput), 1186 Integer.valueOf(location)); 1187 IStateTransform setAttributeName = new PropertyChangeTransform( 1188 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1189 GLStateType.PROGRAM_STATE, 1190 GLStateType.PROGRAMS, 1191 Integer.valueOf(program), 1192 activeInput, 1193 Integer.valueOf(location), 1194 inputName), 1195 name); 1196 IStateTransform setAttributeType = new PropertyChangeTransform( 1197 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1198 GLStateType.PROGRAM_STATE, 1199 GLStateType.PROGRAMS, 1200 Integer.valueOf(program), 1201 activeInput, 1202 Integer.valueOf(location), 1203 inputType), 1204 type); 1205 IStateTransform setAttributeSize = new PropertyChangeTransform( 1206 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1207 GLStateType.PROGRAM_STATE, 1208 GLStateType.PROGRAMS, 1209 Integer.valueOf(program), 1210 activeInput, 1211 Integer.valueOf(location), 1212 inputSize), 1213 Integer.valueOf(size)); 1214 return Arrays.asList(addAttribute, setAttributeName, setAttributeType, setAttributeSize); 1215 } 1216 1217 private static List<IStateTransform> transformsForGlGetActiveAttrib(GLMessage msg) { 1218 return transformsForGlGetActiveAttribOrUniform(msg, true); 1219 } 1220 1221 private static List<IStateTransform> transformsForGlGetActiveUniform(GLMessage msg) { 1222 return transformsForGlGetActiveAttribOrUniform(msg, false); 1223 } 1224 1225 private static List<IStateTransform> transformsForGlUniformMatrix(GLMessage msg) { 1226 // void glUniformMatrix[2|3|4]fv(GLint location, GLsizei count, GLboolean transpose, 1227 // const GLfloat *value); 1228 int location = msg.getArgs(0).getIntValue(0); 1229 List<Float> uniforms = msg.getArgs(3).getFloatValueList(); 1230 1231 IStateTransform setValues = new PropertyChangeTransform( 1232 new CurrentProgramPropertyAccessor(msg.getContextId(), 1233 GLStateType.ACTIVE_UNIFORMS, 1234 location, 1235 GLStateType.UNIFORM_VALUE), 1236 uniforms); 1237 1238 return Collections.singletonList(setValues); 1239 } 1240 1241 private static List<IStateTransform> transformsForGlUniformv(GLMessage msg, boolean isFloats) { 1242 // void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); 1243 int location = msg.getArgs(0).getIntValue(0); 1244 List<?> uniforms; 1245 if (isFloats) { 1246 uniforms = msg.getArgs(2).getFloatValueList(); 1247 } else { 1248 uniforms = msg.getArgs(2).getIntValueList(); 1249 } 1250 1251 IStateTransform setValues = new PropertyChangeTransform( 1252 new CurrentProgramPropertyAccessor(msg.getContextId(), 1253 GLStateType.ACTIVE_UNIFORMS, 1254 location, 1255 GLStateType.UNIFORM_VALUE), 1256 uniforms); 1257 1258 return Collections.singletonList(setValues); 1259 } 1260 1261 private static List<IStateTransform> transformsForGlUniform(GLMessage msg, boolean isFloats) { 1262 // void glUniform1f(GLint location, GLfloat v0); 1263 // void glUniform2f(GLint location, GLfloat v0, GLfloat v1); 1264 // .. 3f 1265 // .. 4f 1266 // void glUniform1i(GLint location, GLfloat v0); 1267 // void glUniform2i(GLint location, GLfloat v0, GLfloat v1); 1268 // .. 3i 1269 // .. 4i 1270 1271 int location = msg.getArgs(0).getIntValue(0); 1272 if (location < 0) { 1273 throw new IllegalArgumentException("Argument location cannot be less than 0."); 1274 } 1275 List<?> uniforms; 1276 if (isFloats) { 1277 List<Float> args = new ArrayList<Float>(msg.getArgsCount() - 1); 1278 for (int i = 1; i < msg.getArgsCount(); i++) { 1279 args.add(Float.valueOf(msg.getArgs(1).getFloatValue(0))); 1280 } 1281 uniforms = args; 1282 } else { 1283 List<Integer> args = new ArrayList<Integer>(msg.getArgsCount() - 1); 1284 for (int i = 1; i < msg.getArgsCount(); i++) { 1285 args.add(Integer.valueOf(msg.getArgs(1).getIntValue(0))); 1286 } 1287 uniforms = args; 1288 } 1289 1290 IStateTransform setValues = new PropertyChangeTransform( 1291 new CurrentProgramPropertyAccessor(msg.getContextId(), 1292 GLStateType.ACTIVE_UNIFORMS, 1293 location, 1294 GLStateType.UNIFORM_VALUE), 1295 uniforms); 1296 1297 return Collections.singletonList(setValues); 1298 } 1299 1300 private static List<IStateTransform> transformsForGlCreateShader(GLMessage msg) { 1301 // GLuint glCreateShader(GLenum shaderType); 1302 GLEnum shaderType = GLEnum.valueOf(msg.getArgs(0).getIntValue(0)); 1303 int shader = msg.getReturnValue().getIntValue(0); 1304 1305 IStateTransform addShader = new SparseArrayElementAddTransform( 1306 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1307 GLStateType.SHADERS), 1308 shader); 1309 IStateTransform setShaderType = new PropertyChangeTransform( 1310 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1311 GLStateType.SHADERS, 1312 Integer.valueOf(shader), 1313 GLStateType.SHADER_TYPE), 1314 shaderType); 1315 return Arrays.asList(addShader, setShaderType); 1316 } 1317 1318 private static List<IStateTransform> transformsForGlDeleteShader(GLMessage msg) { 1319 // void glDeleteShader(GLuint shader); 1320 int shader = msg.getArgs(0).getIntValue(0); 1321 1322 IStateTransform transform = new SparseArrayElementRemoveTransform( 1323 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1324 GLStateType.SHADERS), 1325 shader); 1326 return Collections.singletonList(transform); 1327 } 1328 1329 private static List<IStateTransform> transformsForGlShaderSource(GLMessage msg) { 1330 // void glShaderSource(GLuint shader, GLsizei count, const GLchar **string, 1331 // const GLint *length); 1332 // This message is patched up on the device to return a single string as opposed to a 1333 // list of strings 1334 int shader = msg.getArgs(0).getIntValue(0); 1335 String src = msg.getArgs(2).getCharValue(0).toStringUtf8(); 1336 1337 IStateTransform transform = new PropertyChangeTransform( 1338 GLPropertyAccessor.makeAccessor(msg.getContextId(), 1339 GLStateType.SHADERS, 1340 Integer.valueOf(shader), 1341 GLStateType.SHADER_SOURCE), 1342 src); 1343 return Collections.singletonList(transform); 1344 } 1345 1346 private static List<IStateTransform> transformsForEglCreateContext(GLMessage msg) { 1347 // void eglCreateContext(int version, int context); 1348 int version = msg.getArgs(0).getIntValue(0); 1349 IGLProperty glState = null; 1350 if (version == 0) { 1351 glState = GLState.createDefaultES1State(); 1352 } else { 1353 glState = GLState.createDefaultES2State(); 1354 } 1355 IStateTransform transform = new ListElementAddTransform(null, glState); 1356 return Collections.singletonList(transform); 1357 } 1358 } 1359