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