OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <list> | 10 #include <list> |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 const char* function_name_; | 297 const char* function_name_; |
298 ErrorState* error_state_; | 298 ErrorState* error_state_; |
299 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); | 299 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); |
300 }; | 300 }; |
301 | 301 |
302 // Temporarily changes a decoder's bound texture and restore it when this | 302 // Temporarily changes a decoder's bound texture and restore it when this |
303 // object goes out of scope. Also temporarily switches to using active texture | 303 // object goes out of scope. Also temporarily switches to using active texture |
304 // unit zero in case the client has changed that to something invalid. | 304 // unit zero in case the client has changed that to something invalid. |
305 class ScopedTextureBinder { | 305 class ScopedTextureBinder { |
306 public: | 306 public: |
307 ScopedTextureBinder(ContextState* state, GLuint id, GLenum target); | 307 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target); |
308 ~ScopedTextureBinder(); | 308 ~ScopedTextureBinder(); |
309 | 309 |
310 private: | 310 private: |
311 ContextState* state_; | 311 ContextState* state_; |
312 GLenum target_; | 312 GLenum target_; |
313 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder); | 313 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder); |
314 }; | 314 }; |
315 | 315 |
316 // Temporarily changes a decoder's bound render buffer and restore it when this | 316 // Temporarily changes a decoder's bound render buffer and restore it when this |
317 // object goes out of scope. | 317 // object goes out of scope. |
318 class ScopedRenderBufferBinder { | 318 class ScopedRenderBufferBinder { |
319 public: | 319 public: |
320 ScopedRenderBufferBinder(ContextState* state, GLuint id); | 320 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id); |
321 ~ScopedRenderBufferBinder(); | 321 ~ScopedRenderBufferBinder(); |
322 | 322 |
323 private: | 323 private: |
324 ContextState* state_; | 324 ContextState* state_; |
325 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); | 325 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); |
326 }; | 326 }; |
327 | 327 |
328 // Temporarily changes a decoder's bound frame buffer and restore it when this | 328 // Temporarily changes a decoder's bound frame buffer and restore it when this |
329 // object goes out of scope. | 329 // object goes out of scope. |
330 class ScopedFrameBufferBinder { | 330 class ScopedFrameBufferBinder { |
331 public: | 331 public: |
332 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); | 332 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); |
333 ~ScopedFrameBufferBinder(); | 333 ~ScopedFrameBufferBinder(); |
334 | 334 |
335 private: | 335 private: |
336 GLES2DecoderImpl* decoder_; | 336 GLES2DecoderImpl* decoder_; |
337 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); | 337 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); |
338 }; | 338 }; |
339 | 339 |
340 // Temporarily changes a decoder's bound frame buffer to a resolved version of | 340 // Temporarily changes a decoder's bound frame buffer to a resolved version of |
341 // the multisampled offscreen render buffer if that buffer is multisampled, and, | 341 // the multisampled offscreen render buffer if that buffer is multisampled, and, |
342 // if it is bound or enforce_internal_framebuffer is true. If internal is | 342 // if it is bound or enforce_internal_framebuffer is true. If internal is |
343 // true, the resolved framebuffer is not visible to the parent. | 343 // true, the resolved framebuffer is not visible to the parent. |
344 class ScopedResolvedFrameBufferBinder { | 344 class ScopedResolvedFrameBufferBinder { |
345 public: | 345 public: |
346 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder, | 346 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder, |
347 bool enforce_internal_framebuffer, | 347 bool enforce_internal_framebuffer, |
348 bool internal); | 348 bool internal); |
349 ~ScopedResolvedFrameBufferBinder(); | 349 ~ScopedResolvedFrameBufferBinder(); |
350 | 350 |
351 private: | 351 private: |
352 GLES2DecoderImpl* decoder_; | 352 GLES2DecoderImpl* decoder_; |
353 bool resolve_and_bind_; | 353 bool resolve_and_bind_; |
354 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); | 354 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); |
355 }; | 355 }; |
356 | 356 |
| 357 class ScopedModifyPixels { |
| 358 public: |
| 359 explicit ScopedModifyPixels(TextureRef* ref); |
| 360 ~ScopedModifyPixels(); |
| 361 |
| 362 private: |
| 363 TextureRef* ref_; |
| 364 }; |
| 365 |
| 366 ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) { |
| 367 if (ref_) |
| 368 ref_->texture()->OnWillModifyPixels(); |
| 369 } |
| 370 |
| 371 ScopedModifyPixels::~ScopedModifyPixels() { |
| 372 if (ref_) |
| 373 ref_->texture()->OnDidModifyPixels(); |
| 374 } |
| 375 |
| 376 class ScopedRenderTo { |
| 377 public: |
| 378 explicit ScopedRenderTo(Framebuffer* framebuffer); |
| 379 ~ScopedRenderTo(); |
| 380 |
| 381 private: |
| 382 const Framebuffer* framebuffer_; |
| 383 }; |
| 384 |
| 385 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer) |
| 386 : framebuffer_(framebuffer) { |
| 387 if (framebuffer) |
| 388 framebuffer_->OnWillRenderTo(); |
| 389 } |
| 390 |
| 391 ScopedRenderTo::~ScopedRenderTo() { |
| 392 if (framebuffer_) |
| 393 framebuffer_->OnDidRenderTo(); |
| 394 } |
| 395 |
357 // Encapsulates an OpenGL texture. | 396 // Encapsulates an OpenGL texture. |
358 class BackTexture { | 397 class BackTexture { |
359 public: | 398 public: |
360 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); | 399 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); |
361 ~BackTexture(); | 400 ~BackTexture(); |
362 | 401 |
363 // Create a new render texture. | 402 // Create a new render texture. |
364 void Create(); | 403 void Create(); |
365 | 404 |
366 // Set the initial size and format of a render texture or resize it. | 405 // Set the initial size and format of a render texture or resize it. |
(...skipping 5934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6301 if (!SimulateAttrib0( | 6340 if (!SimulateAttrib0( |
6302 function_name, max_vertex_accessed, &simulated_attrib_0)) { | 6341 function_name, max_vertex_accessed, &simulated_attrib_0)) { |
6303 return error::kNoError; | 6342 return error::kNoError; |
6304 } | 6343 } |
6305 bool simulated_fixed_attribs = false; | 6344 bool simulated_fixed_attribs = false; |
6306 if (SimulateFixedAttribs( | 6345 if (SimulateFixedAttribs( |
6307 function_name, max_vertex_accessed, &simulated_fixed_attribs, | 6346 function_name, max_vertex_accessed, &simulated_fixed_attribs, |
6308 primcount)) { | 6347 primcount)) { |
6309 bool textures_set = !PrepareTexturesForRender(); | 6348 bool textures_set = !PrepareTexturesForRender(); |
6310 ApplyDirtyState(); | 6349 ApplyDirtyState(); |
| 6350 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); |
6311 if (!instanced) { | 6351 if (!instanced) { |
6312 glDrawArrays(mode, first, count); | 6352 glDrawArrays(mode, first, count); |
6313 } else { | 6353 } else { |
6314 glDrawArraysInstancedANGLE(mode, first, count, primcount); | 6354 glDrawArraysInstancedANGLE(mode, first, count, primcount); |
6315 } | 6355 } |
6316 ProcessPendingQueries(); | 6356 ProcessPendingQueries(); |
6317 if (textures_set) { | 6357 if (textures_set) { |
6318 RestoreStateForTextures(); | 6358 RestoreStateForTextures(); |
6319 } | 6359 } |
6320 if (simulated_fixed_attribs) { | 6360 if (simulated_fixed_attribs) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6430 // TODO(gman): Refactor to hide these details in BufferManager or | 6470 // TODO(gman): Refactor to hide these details in BufferManager or |
6431 // VertexAttribManager. | 6471 // VertexAttribManager. |
6432 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 6472 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
6433 bool used_client_side_array = false; | 6473 bool used_client_side_array = false; |
6434 if (element_array_buffer->IsClientSideArray()) { | 6474 if (element_array_buffer->IsClientSideArray()) { |
6435 used_client_side_array = true; | 6475 used_client_side_array = true; |
6436 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 6476 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
6437 indices = element_array_buffer->GetRange(offset, 0); | 6477 indices = element_array_buffer->GetRange(offset, 0); |
6438 } | 6478 } |
6439 | 6479 |
| 6480 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); |
6440 if (!instanced) { | 6481 if (!instanced) { |
6441 glDrawElements(mode, count, type, indices); | 6482 glDrawElements(mode, count, type, indices); |
6442 } else { | 6483 } else { |
6443 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); | 6484 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); |
6444 } | 6485 } |
6445 | 6486 |
6446 if (used_client_side_array) { | 6487 if (used_client_side_array) { |
6447 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, | 6488 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, |
6448 element_array_buffer->service_id()); | 6489 element_array_buffer->service_id()); |
6449 } | 6490 } |
(...skipping 1807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8257 width, height, texture->IsImmutable())) { | 8298 width, height, texture->IsImmutable())) { |
8258 LOCAL_SET_GL_ERROR( | 8299 LOCAL_SET_GL_ERROR( |
8259 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); | 8300 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); |
8260 return; | 8301 return; |
8261 } | 8302 } |
8262 if (copyHeight > 0 && copyWidth > 0) { | 8303 if (copyHeight > 0 && copyWidth > 0) { |
8263 GLint dx = copyX - x; | 8304 GLint dx = copyX - x; |
8264 GLint dy = copyY - y; | 8305 GLint dy = copyY - y; |
8265 GLint destX = dx; | 8306 GLint destX = dx; |
8266 GLint destY = dy; | 8307 GLint destY = dy; |
| 8308 ScopedModifyPixels modify(texture_ref); |
8267 glCopyTexSubImage2D(target, level, | 8309 glCopyTexSubImage2D(target, level, |
8268 destX, destY, copyX, copyY, | 8310 destX, destY, copyX, copyY, |
8269 copyWidth, copyHeight); | 8311 copyWidth, copyHeight); |
8270 } | 8312 } |
8271 } else { | 8313 } else { |
| 8314 ScopedModifyPixels modify(texture_ref); |
8272 glCopyTexImage2D(target, level, internal_format, | 8315 glCopyTexImage2D(target, level, internal_format, |
8273 copyX, copyY, copyWidth, copyHeight, border); | 8316 copyX, copyY, copyWidth, copyHeight, border); |
8274 } | 8317 } |
8275 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); | 8318 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); |
8276 if (error == GL_NO_ERROR) { | 8319 if (error == GL_NO_ERROR) { |
8277 texture_manager()->SetLevelInfo( | 8320 texture_manager()->SetLevelInfo( |
8278 texture_ref, target, level, internal_format, width, height, 1, | 8321 texture_ref, target, level, internal_format, width, height, 1, |
8279 border, internal_format, GL_UNSIGNED_BYTE, true); | 8322 border, internal_format, GL_UNSIGNED_BYTE, true); |
8280 } | 8323 } |
8281 } | 8324 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8361 uint32 pixels_size = 0; | 8404 uint32 pixels_size = 0; |
8362 if (!GLES2Util::ComputeImageDataSizes( | 8405 if (!GLES2Util::ComputeImageDataSizes( |
8363 width, height, format, type, state_.unpack_alignment, &pixels_size, | 8406 width, height, format, type, state_.unpack_alignment, &pixels_size, |
8364 NULL, NULL)) { | 8407 NULL, NULL)) { |
8365 LOCAL_SET_GL_ERROR( | 8408 LOCAL_SET_GL_ERROR( |
8366 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); | 8409 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); |
8367 return; | 8410 return; |
8368 } | 8411 } |
8369 scoped_ptr<char[]> zero(new char[pixels_size]); | 8412 scoped_ptr<char[]> zero(new char[pixels_size]); |
8370 memset(zero.get(), 0, pixels_size); | 8413 memset(zero.get(), 0, pixels_size); |
| 8414 ScopedModifyPixels modify(texture_ref); |
8371 glTexSubImage2D( | 8415 glTexSubImage2D( |
8372 target, level, xoffset, yoffset, width, height, | 8416 target, level, xoffset, yoffset, width, height, |
8373 format, type, zero.get()); | 8417 format, type, zero.get()); |
8374 } | 8418 } |
8375 | 8419 |
8376 if (copyHeight > 0 && copyWidth > 0) { | 8420 if (copyHeight > 0 && copyWidth > 0) { |
8377 GLint dx = copyX - x; | 8421 GLint dx = copyX - x; |
8378 GLint dy = copyY - y; | 8422 GLint dy = copyY - y; |
8379 GLint destX = xoffset + dx; | 8423 GLint destX = xoffset + dx; |
8380 GLint destY = yoffset + dy; | 8424 GLint destY = yoffset + dy; |
| 8425 ScopedModifyPixels modify(texture_ref); |
8381 glCopyTexSubImage2D(target, level, | 8426 glCopyTexSubImage2D(target, level, |
8382 destX, destY, copyX, copyY, | 8427 destX, destY, copyX, copyY, |
8383 copyWidth, copyHeight); | 8428 copyWidth, copyHeight); |
8384 } | 8429 } |
8385 } | 8430 } |
8386 | 8431 |
8387 bool GLES2DecoderImpl::ValidateTexSubImage2D( | 8432 bool GLES2DecoderImpl::ValidateTexSubImage2D( |
8388 error::Error* error, | 8433 error::Error* error, |
8389 const char* function_name, | 8434 const char* function_name, |
8390 GLenum target, | 8435 GLenum target, |
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9242 return error::kLostContext; | 9287 return error::kLostContext; |
9243 } | 9288 } |
9244 | 9289 |
9245 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM( | 9290 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM( |
9246 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) { | 9291 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) { |
9247 return error::kUnknownCommand; | 9292 return error::kUnknownCommand; |
9248 } | 9293 } |
9249 | 9294 |
9250 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM( | 9295 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM( |
9251 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) { | 9296 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) { |
| 9297 group_->mailbox_manager()->PullTextureUpdates(); |
9252 if (wait_sync_point_callback_.is_null()) | 9298 if (wait_sync_point_callback_.is_null()) |
9253 return error::kNoError; | 9299 return error::kNoError; |
9254 | 9300 |
9255 return wait_sync_point_callback_.Run(c.sync_point) ? | 9301 return wait_sync_point_callback_.Run(c.sync_point) ? |
9256 error::kNoError : error::kDeferCommandUntilLater; | 9302 error::kNoError : error::kDeferCommandUntilLater; |
9257 } | 9303 } |
9258 | 9304 |
9259 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM( | 9305 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM( |
9260 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) { | 9306 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) { |
9261 if (surface_->DeferDraws()) | 9307 if (surface_->DeferDraws()) |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9791 | 9837 |
9792 texture_manager()->SetLevelInfo( | 9838 texture_manager()->SetLevelInfo( |
9793 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width, | 9839 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width, |
9794 source_height, 1, 0, internal_format, dest_type, true); | 9840 source_height, 1, 0, internal_format, dest_type, true); |
9795 } else { | 9841 } else { |
9796 texture_manager()->SetLevelCleared( | 9842 texture_manager()->SetLevelCleared( |
9797 dest_texture_ref, GL_TEXTURE_2D, level, true); | 9843 dest_texture_ref, GL_TEXTURE_2D, level, true); |
9798 } | 9844 } |
9799 | 9845 |
9800 DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); | 9846 DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); |
| 9847 ScopedModifyPixels modify(dest_texture_ref); |
9801 | 9848 |
9802 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix | 9849 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix |
9803 // before presenting. | 9850 // before presenting. |
9804 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { | 9851 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { |
9805 // TODO(hkuang): get the StreamTexture transform matrix in GPU process | 9852 // TODO(hkuang): get the StreamTexture transform matrix in GPU process |
9806 // instead of using default matrix crbug.com/226218. | 9853 // instead of using default matrix crbug.com/226218. |
9807 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, | 9854 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, |
9808 0.0f, 1.0f, 0.0f, 0.0f, | 9855 0.0f, 1.0f, 0.0f, 0.0f, |
9809 0.0f, 0.0f, 1.0f, 0.0f, | 9856 0.0f, 0.0f, 1.0f, 0.0f, |
9810 0.0f, 0.0f, 0.0f, 1.0f}; | 9857 0.0f, 0.0f, 0.0f, 1.0f}; |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10497 DoDidUseTexImageIfNeeded(texture, texture->target()); | 10544 DoDidUseTexImageIfNeeded(texture, texture->target()); |
10498 } | 10545 } |
10499 | 10546 |
10500 // Include the auto-generated part of this file. We split this because it means | 10547 // Include the auto-generated part of this file. We split this because it means |
10501 // we can easily edit the non-auto generated parts right here in this file | 10548 // we can easily edit the non-auto generated parts right here in this file |
10502 // instead of having to edit some template or the code generator. | 10549 // instead of having to edit some template or the code generator. |
10503 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10550 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
10504 | 10551 |
10505 } // namespace gles2 | 10552 } // namespace gles2 |
10506 } // namespace gpu | 10553 } // namespace gpu |
OLD | NEW |