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 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 6 7 #include <stdio.h> 8 9 #include <algorithm> 10 #include <list> 11 #include <map> 12 #include <stack> 13 #include <string> 14 #include <vector> 15 16 #include "base/at_exit.h" 17 #include "base/atomicops.h" 18 #include "base/bind.h" 19 #include "base/command_line.h" 20 #include "base/debug/trace_event.h" 21 #if defined(OS_MACOSX) 22 #include "base/mac/scoped_cftyperef.h" 23 #endif 24 #include "base/memory/scoped_ptr.h" 25 #include "base/strings/string_number_conversions.h" 26 #include "build/build_config.h" 27 #define GLES2_GPU_SERVICE 1 28 #include "gpu/command_buffer/common/debug_marker_manager.h" 29 #include "gpu/command_buffer/common/gles2_cmd_format.h" 30 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 31 #include "gpu/command_buffer/common/id_allocator.h" 32 #include "gpu/command_buffer/common/mailbox.h" 33 #include "gpu/command_buffer/service/async_pixel_transfer_delegate.h" 34 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" 35 #include "gpu/command_buffer/service/buffer_manager.h" 36 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 37 #include "gpu/command_buffer/service/context_group.h" 38 #include "gpu/command_buffer/service/context_state.h" 39 #include "gpu/command_buffer/service/error_state.h" 40 #include "gpu/command_buffer/service/feature_info.h" 41 #include "gpu/command_buffer/service/framebuffer_manager.h" 42 #include "gpu/command_buffer/service/gl_utils.h" 43 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" 44 #include "gpu/command_buffer/service/gles2_cmd_validation.h" 45 #include "gpu/command_buffer/service/gpu_switches.h" 46 #include "gpu/command_buffer/service/gpu_tracer.h" 47 #include "gpu/command_buffer/service/image_manager.h" 48 #include "gpu/command_buffer/service/mailbox_manager.h" 49 #include "gpu/command_buffer/service/memory_tracking.h" 50 #include "gpu/command_buffer/service/program_manager.h" 51 #include "gpu/command_buffer/service/query_manager.h" 52 #include "gpu/command_buffer/service/renderbuffer_manager.h" 53 #include "gpu/command_buffer/service/shader_manager.h" 54 #include "gpu/command_buffer/service/shader_translator.h" 55 #include "gpu/command_buffer/service/shader_translator_cache.h" 56 #include "gpu/command_buffer/service/stream_texture.h" 57 #include "gpu/command_buffer/service/stream_texture_manager.h" 58 #include "gpu/command_buffer/service/texture_manager.h" 59 #include "gpu/command_buffer/service/vertex_array_manager.h" 60 #include "gpu/command_buffer/service/vertex_attrib_manager.h" 61 #include "ui/gl/gl_bindings.h" 62 #include "ui/gl/gl_fence.h" 63 #include "ui/gl/gl_image.h" 64 #include "ui/gl/gl_implementation.h" 65 #include "ui/gl/gl_surface.h" 66 67 #if defined(OS_MACOSX) 68 #include "ui/gl/io_surface_support_mac.h" 69 #endif 70 71 // TODO(zmo): we can't include "City.h" due to type def conflicts. 72 extern uint64 CityHash64(const char*, size_t); 73 74 namespace gpu { 75 namespace gles2 { 76 77 namespace { 78 79 static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives"; 80 static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth"; 81 static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers"; 82 83 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108 84 khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) { 85 return static_cast<khronos_uint64_t>( 86 CityHash64(name, static_cast<size_t>(len))); 87 } 88 #endif 89 90 static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin, 91 GLint rangeMax, 92 GLint precision) { 93 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16); 94 } 95 96 static void GetShaderPrecisionFormatImpl(GLenum shader_type, 97 GLenum precision_type, 98 GLint *range, GLint *precision) { 99 switch (precision_type) { 100 case GL_LOW_INT: 101 case GL_MEDIUM_INT: 102 case GL_HIGH_INT: 103 // These values are for a 32-bit twos-complement integer format. 104 range[0] = 31; 105 range[1] = 30; 106 *precision = 0; 107 break; 108 case GL_LOW_FLOAT: 109 case GL_MEDIUM_FLOAT: 110 case GL_HIGH_FLOAT: 111 // These values are for an IEEE single-precision floating-point format. 112 range[0] = 127; 113 range[1] = 127; 114 *precision = 23; 115 break; 116 default: 117 NOTREACHED(); 118 break; 119 } 120 121 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 && 122 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) { 123 // This function is sometimes defined even though it's really just 124 // a stub, so we need to set range and precision as if it weren't 125 // defined before calling it. 126 // On Mac OS with some GPUs, calling this generates a 127 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2 128 // platforms. 129 glGetShaderPrecisionFormat(shader_type, precision_type, 130 range, precision); 131 132 // TODO(brianderson): Make the following official workarounds. 133 134 // Some drivers have bugs where they report the ranges as a negative number. 135 // Taking the absolute value here shouldn't hurt because negative numbers 136 // aren't expected anyway. 137 range[0] = abs(range[0]); 138 range[1] = abs(range[1]); 139 140 // If the driver reports a precision for highp float that isn't actually 141 // highp, don't pretend like it's supported because shader compilation will 142 // fail anyway. 143 if (precision_type == GL_HIGH_FLOAT && 144 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) { 145 range[0] = 0; 146 range[1] = 0; 147 *precision = 0; 148 } 149 } 150 } 151 152 } // namespace 153 154 class GLES2DecoderImpl; 155 156 // Local versions of the SET_GL_ERROR macros 157 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ 158 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) 159 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ 160 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ 161 function_name, value, label) 162 #define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \ 163 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \ 164 function_name, pname) 165 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \ 166 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \ 167 function_name) 168 #define LOCAL_PEEK_GL_ERROR(function_name) \ 169 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name) 170 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \ 171 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name) 172 #define LOCAL_PERFORMANCE_WARNING(msg) \ 173 PerformanceWarning(__FILE__, __LINE__, msg) 174 #define LOCAL_RENDER_WARNING(msg) \ 175 RenderWarning(__FILE__, __LINE__, msg) 176 177 // Check that certain assumptions the code makes are true. There are places in 178 // the code where shared memory is passed direclty to GL. Example, glUniformiv, 179 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe 180 // a few others) are 32bits. If they are not 32bits the code will have to change 181 // to call those GL functions with service side memory and then copy the results 182 // to shared memory, converting the sizes. 183 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT 184 GLint_not_same_size_as_uint32); 185 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT 186 GLint_not_same_size_as_uint32); 187 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT 188 GLfloat_not_same_size_as_float); 189 190 // TODO(kbr): the use of this anonymous namespace core dumps the 191 // linker on Mac OS X 10.6 when the symbol ordering file is used 192 // namespace { 193 194 // Returns the address of the first byte after a struct. 195 template <typename T> 196 const void* AddressAfterStruct(const T& pod) { 197 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); 198 } 199 200 // Returns the address of the frst byte after the struct or NULL if size > 201 // immediate_data_size. 202 template <typename RETURN_TYPE, typename COMMAND_TYPE> 203 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod, 204 uint32 size, 205 uint32 immediate_data_size) { 206 return (size <= immediate_data_size) ? 207 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) : 208 NULL; 209 } 210 211 // Computes the data size for certain gl commands like glUniform. 212 bool ComputeDataSize( 213 GLuint count, 214 size_t size, 215 unsigned int elements_per_unit, 216 uint32* dst) { 217 uint32 value; 218 if (!SafeMultiplyUint32(count, size, &value)) { 219 return false; 220 } 221 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) { 222 return false; 223 } 224 *dst = value; 225 return true; 226 } 227 228 // A struct to hold info about each command. 229 struct CommandInfo { 230 int arg_flags; // How to handle the arguments for this command 231 int arg_count; // How many arguments are expected for this command. 232 }; 233 234 // A table of CommandInfo for all the commands. 235 const CommandInfo g_command_info[] = { 236 #define GLES2_CMD_OP(name) { \ 237 cmds::name::kArgFlags, \ 238 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ 239 240 GLES2_COMMAND_LIST(GLES2_CMD_OP) 241 242 #undef GLES2_CMD_OP 243 }; 244 245 // Return true if a character belongs to the ASCII subset as defined in 246 // GLSL ES 1.0 spec section 3.1. 247 static bool CharacterIsValidForGLES(unsigned char c) { 248 // Printing characters are valid except " $ ` @ \ ' DEL. 249 if (c >= 32 && c <= 126 && 250 c != '"' && 251 c != '$' && 252 c != '`' && 253 c != '@' && 254 c != '\\' && 255 c != '\'') { 256 return true; 257 } 258 // Horizontal tab, line feed, vertical tab, form feed, carriage return 259 // are also valid. 260 if (c >= 9 && c <= 13) { 261 return true; 262 } 263 264 return false; 265 } 266 267 static bool StringIsValidForGLES(const char* str) { 268 for (; *str; ++str) { 269 if (!CharacterIsValidForGLES(*str)) { 270 return false; 271 } 272 } 273 return true; 274 } 275 276 // Wrapper for glEnable/glDisable that doesn't suck. 277 static void EnableDisable(GLenum pname, bool enable) { 278 if (enable) { 279 glEnable(pname); 280 } else { 281 glDisable(pname); 282 } 283 } 284 285 // This class prevents any GL errors that occur when it is in scope from 286 // being reported to the client. 287 class ScopedGLErrorSuppressor { 288 public: 289 explicit ScopedGLErrorSuppressor( 290 const char* function_name, GLES2DecoderImpl* decoder); 291 ~ScopedGLErrorSuppressor(); 292 private: 293 const char* function_name_; 294 GLES2DecoderImpl* decoder_; 295 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); 296 }; 297 298 // Temporarily changes a decoder's bound 2D texture and restore it when this 299 // object goes out of scope. Also temporarily switches to using active texture 300 // unit zero in case the client has changed that to something invalid. 301 class ScopedTexture2DBinder { 302 public: 303 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id); 304 ~ScopedTexture2DBinder(); 305 306 private: 307 GLES2DecoderImpl* decoder_; 308 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder); 309 }; 310 311 // Temporarily changes a decoder's bound render buffer and restore it when this 312 // object goes out of scope. 313 class ScopedRenderBufferBinder { 314 public: 315 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id); 316 ~ScopedRenderBufferBinder(); 317 318 private: 319 GLES2DecoderImpl* decoder_; 320 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); 321 }; 322 323 // Temporarily changes a decoder's bound frame buffer and restore it when this 324 // object goes out of scope. 325 class ScopedFrameBufferBinder { 326 public: 327 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); 328 ~ScopedFrameBufferBinder(); 329 330 private: 331 GLES2DecoderImpl* decoder_; 332 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); 333 }; 334 335 // Temporarily changes a decoder's bound frame buffer to a resolved version of 336 // the multisampled offscreen render buffer if that buffer is multisampled, and, 337 // if it is bound or enforce_internal_framebuffer is true. If internal is 338 // true, the resolved framebuffer is not visible to the parent. 339 class ScopedResolvedFrameBufferBinder { 340 public: 341 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder, 342 bool enforce_internal_framebuffer, 343 bool internal); 344 ~ScopedResolvedFrameBufferBinder(); 345 346 private: 347 GLES2DecoderImpl* decoder_; 348 bool resolve_and_bind_; 349 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); 350 }; 351 352 // This class records texture upload time when in scope. 353 class ScopedTextureUploadTimer { 354 public: 355 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder); 356 ~ScopedTextureUploadTimer(); 357 358 private: 359 GLES2DecoderImpl* decoder_; 360 base::TimeTicks begin_time_; 361 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer); 362 }; 363 364 // Encapsulates an OpenGL texture. 365 class BackTexture { 366 public: 367 explicit BackTexture(GLES2DecoderImpl* decoder); 368 ~BackTexture(); 369 370 // Create a new render texture. 371 void Create(); 372 373 // Set the initial size and format of a render texture or resize it. 374 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero); 375 376 // Copy the contents of the currently bound frame buffer. 377 void Copy(const gfx::Size& size, GLenum format); 378 379 // Destroy the render texture. This must be explicitly called before 380 // destroying this object. 381 void Destroy(); 382 383 // Invalidate the texture. This can be used when a context is lost and it is 384 // not possible to make it current in order to free the resource. 385 void Invalidate(); 386 387 GLuint id() const { 388 return id_; 389 } 390 391 gfx::Size size() const { 392 return size_; 393 } 394 395 size_t estimated_size() const { 396 return memory_tracker_.GetMemRepresented(); 397 } 398 399 private: 400 GLES2DecoderImpl* decoder_; 401 MemoryTypeTracker memory_tracker_; 402 size_t bytes_allocated_; 403 GLuint id_; 404 gfx::Size size_; 405 DISALLOW_COPY_AND_ASSIGN(BackTexture); 406 }; 407 408 // Encapsulates an OpenGL render buffer of any format. 409 class BackRenderbuffer { 410 public: 411 explicit BackRenderbuffer(GLES2DecoderImpl* decoder); 412 ~BackRenderbuffer(); 413 414 // Create a new render buffer. 415 void Create(); 416 417 // Set the initial size and format of a render buffer or resize it. 418 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples); 419 420 // Destroy the render buffer. This must be explicitly called before destroying 421 // this object. 422 void Destroy(); 423 424 // Invalidate the render buffer. This can be used when a context is lost and 425 // it is not possible to make it current in order to free the resource. 426 void Invalidate(); 427 428 GLuint id() const { 429 return id_; 430 } 431 432 size_t estimated_size() const { 433 return memory_tracker_.GetMemRepresented(); 434 } 435 436 private: 437 GLES2DecoderImpl* decoder_; 438 MemoryTypeTracker memory_tracker_; 439 size_t bytes_allocated_; 440 GLuint id_; 441 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer); 442 }; 443 444 // Encapsulates an OpenGL frame buffer. 445 class BackFramebuffer { 446 public: 447 explicit BackFramebuffer(GLES2DecoderImpl* decoder); 448 ~BackFramebuffer(); 449 450 // Create a new frame buffer. 451 void Create(); 452 453 // Attach a color render buffer to a frame buffer. 454 void AttachRenderTexture(BackTexture* texture); 455 456 // Attach a render buffer to a frame buffer. Note that this unbinds any 457 // currently bound frame buffer. 458 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer); 459 460 // Destroy the frame buffer. This must be explicitly called before destroying 461 // this object. 462 void Destroy(); 463 464 // Invalidate the frame buffer. This can be used when a context is lost and it 465 // is not possible to make it current in order to free the resource. 466 void Invalidate(); 467 468 // See glCheckFramebufferStatusEXT. 469 GLenum CheckStatus(); 470 471 GLuint id() const { 472 return id_; 473 } 474 475 private: 476 GLES2DecoderImpl* decoder_; 477 GLuint id_; 478 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer); 479 }; 480 481 struct FenceCallback { 482 explicit FenceCallback() 483 : fence(gfx::GLFence::Create()) { 484 DCHECK(fence); 485 } 486 void AddCallback(base::Closure cb) { 487 callbacks.push_back(cb); 488 } 489 std::vector<base::Closure> callbacks; 490 scoped_ptr<gfx::GLFence> fence; 491 }; 492 493 494 // } // anonymous namespace. 495 496 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, 497 uint32* service_texture_id) { 498 return false; 499 } 500 501 GLES2Decoder::GLES2Decoder() 502 : initialized_(false), 503 debug_(false), 504 log_commands_(false) { 505 } 506 507 GLES2Decoder::~GLES2Decoder() { 508 } 509 510 bool GLES2Decoder::testing_force_is_angle_; 511 512 void GLES2Decoder::set_testing_force_is_angle(bool force) { 513 testing_force_is_angle_ = force; 514 } 515 516 bool GLES2Decoder::IsAngle() { 517 #if defined(OS_WIN) 518 return testing_force_is_angle_ || 519 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; 520 #else 521 return testing_force_is_angle_; 522 #endif 523 } 524 525 // This class implements GLES2Decoder so we don't have to expose all the GLES2 526 // cmd stuff to outside this class. 527 class GLES2DecoderImpl : public GLES2Decoder, 528 public FramebufferManager::TextureDetachObserver { 529 public: 530 // Used by PrepForSetUniformByLocation to validate types. 531 struct BaseUniformInfo { 532 const GLenum* const valid_types; 533 size_t num_valid_types; 534 }; 535 536 explicit GLES2DecoderImpl(ContextGroup* group); 537 virtual ~GLES2DecoderImpl(); 538 539 // Overridden from AsyncAPIInterface. 540 virtual Error DoCommand(unsigned int command, 541 unsigned int arg_count, 542 const void* args) OVERRIDE; 543 544 // Overridden from AsyncAPIInterface. 545 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE; 546 547 // Overridden from GLES2Decoder. 548 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, 549 const scoped_refptr<gfx::GLContext>& context, 550 bool offscreen, 551 const gfx::Size& size, 552 const DisallowedFeatures& disallowed_features, 553 const char* allowed_extensions, 554 const std::vector<int32>& attribs) OVERRIDE; 555 virtual void Destroy(bool have_context) OVERRIDE; 556 virtual void SetSurface( 557 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE; 558 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE; 559 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE; 560 void UpdateParentTextureInfo(); 561 virtual bool MakeCurrent() OVERRIDE; 562 virtual void ReleaseCurrent() OVERRIDE; 563 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; } 564 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); } 565 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); } 566 virtual void RestoreState() const OVERRIDE; 567 568 virtual void RestoreActiveTexture() const OVERRIDE { 569 state_.RestoreActiveTexture(); 570 } 571 virtual void RestoreAllTextureUnitBindings() const OVERRIDE { 572 state_.RestoreAllTextureUnitBindings(); 573 } 574 virtual void RestoreAttribute(unsigned index) const OVERRIDE { 575 state_.RestoreAttribute(index); 576 } 577 virtual void RestoreBufferBindings() const OVERRIDE { 578 state_.RestoreBufferBindings(); 579 } 580 virtual void RestoreGlobalState() const OVERRIDE { 581 state_.RestoreGlobalState(); 582 } 583 virtual void RestoreProgramBindings() const OVERRIDE { 584 state_.RestoreProgramBindings(); 585 } 586 virtual void RestoreRenderbufferBindings() const OVERRIDE { 587 state_.RestoreRenderbufferBindings(); 588 } 589 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE { 590 state_.RestoreTextureUnitBindings(unit); 591 } 592 virtual void RestoreFramebufferBindings() const OVERRIDE; 593 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE; 594 595 virtual QueryManager* GetQueryManager() OVERRIDE { 596 return query_manager_.get(); 597 } 598 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE { 599 return vertex_array_manager_.get(); 600 } 601 virtual bool ProcessPendingQueries() OVERRIDE; 602 virtual bool HasMoreIdleWork() OVERRIDE; 603 virtual void PerformIdleWork() OVERRIDE; 604 605 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE; 606 607 virtual void SetResizeCallback( 608 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE; 609 610 virtual Logger* GetLogger() OVERRIDE; 611 virtual ErrorState* GetErrorState() OVERRIDE; 612 613 virtual void SetShaderCacheCallback( 614 const ShaderCacheCallback& callback) OVERRIDE; 615 virtual void SetWaitSyncPointCallback( 616 const WaitSyncPointCallback& callback) OVERRIDE; 617 618 virtual AsyncPixelTransferManager* 619 GetAsyncPixelTransferManager() OVERRIDE; 620 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE; 621 virtual void SetAsyncPixelTransferManagerForTest( 622 AsyncPixelTransferManager* manager) OVERRIDE; 623 void ProcessFinishedAsyncTransfers(); 624 625 virtual bool GetServiceTextureId(uint32 client_texture_id, 626 uint32* service_texture_id) OVERRIDE; 627 628 virtual uint32 GetTextureUploadCount() OVERRIDE; 629 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; 630 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; 631 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE; 632 633 // Restores the current state to the user's settings. 634 void RestoreCurrentFramebufferBindings(); 635 void RestoreCurrentRenderbufferBindings(); 636 void RestoreCurrentTexture2DBindings(); 637 638 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. 639 void ApplyDirtyState(); 640 641 // These check the state of the currently bound framebuffer or the 642 // backbuffer if no framebuffer is bound. 643 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise 644 // check with all attached and enabled color attachments. 645 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers); 646 bool BoundFramebufferHasDepthAttachment(); 647 bool BoundFramebufferHasStencilAttachment(); 648 649 virtual error::ContextLostReason GetContextLostReason() OVERRIDE; 650 651 // Overridden from FramebufferManager::TextureDetachObserver: 652 virtual void OnTextureRefDetachedFromFramebuffer( 653 TextureRef* texture) OVERRIDE; 654 655 private: 656 friend class ScopedFrameBufferBinder; 657 friend class ScopedGLErrorSuppressor; 658 friend class ScopedResolvedFrameBufferBinder; 659 friend class ScopedTextureUploadTimer; 660 friend class BackTexture; 661 friend class BackRenderbuffer; 662 friend class BackFramebuffer; 663 664 // Initialize or re-initialize the shader translator. 665 bool InitializeShaderTranslator(); 666 667 void UpdateCapabilities(); 668 669 // Helpers for the glGen and glDelete functions. 670 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids); 671 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids); 672 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids); 673 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); 674 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); 675 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); 676 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 677 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 678 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 679 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 680 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 681 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 682 683 // Workarounds 684 void OnFboChanged() const; 685 void OnUseFramebuffer() const; 686 687 // TODO(gman): Cache these pointers? 688 BufferManager* buffer_manager() { 689 return group_->buffer_manager(); 690 } 691 692 RenderbufferManager* renderbuffer_manager() { 693 return group_->renderbuffer_manager(); 694 } 695 696 FramebufferManager* framebuffer_manager() { 697 return group_->framebuffer_manager(); 698 } 699 700 ProgramManager* program_manager() { 701 return group_->program_manager(); 702 } 703 704 ShaderManager* shader_manager() { 705 return group_->shader_manager(); 706 } 707 708 const TextureManager* texture_manager() const { 709 return group_->texture_manager(); 710 } 711 712 TextureManager* texture_manager() { 713 return group_->texture_manager(); 714 } 715 716 MailboxManager* mailbox_manager() { 717 return group_->mailbox_manager(); 718 } 719 720 ImageManager* image_manager() { 721 return group_->image_manager(); 722 } 723 724 VertexArrayManager* vertex_array_manager() { 725 return vertex_array_manager_.get(); 726 } 727 728 MemoryTracker* memory_tracker() { 729 return group_->memory_tracker(); 730 } 731 732 StreamTextureManager* stream_texture_manager() const { 733 return group_->stream_texture_manager(); 734 } 735 736 bool EnsureGPUMemoryAvailable(size_t estimated_size) { 737 MemoryTracker* tracker = memory_tracker(); 738 if (tracker) { 739 return tracker->EnsureGPUMemoryAvailable(estimated_size); 740 } 741 return true; 742 } 743 744 bool IsOffscreenBufferMultisampled() const { 745 return offscreen_target_samples_ > 1; 746 } 747 748 // Creates a Texture for the given texture. 749 TextureRef* CreateTexture( 750 GLuint client_id, GLuint service_id) { 751 return texture_manager()->CreateTexture(client_id, service_id); 752 } 753 754 // Gets the texture info for the given texture. Returns NULL if none exists. 755 TextureRef* GetTexture(GLuint client_id) const { 756 return texture_manager()->GetTexture(client_id); 757 } 758 759 // Deletes the texture info for the given texture. 760 void RemoveTexture(GLuint client_id) { 761 texture_manager()->RemoveTexture(client_id); 762 } 763 764 // Get the size (in pixels) of the currently bound frame buffer (either FBO 765 // or regular back buffer). 766 gfx::Size GetBoundReadFrameBufferSize(); 767 768 // Get the format of the currently bound frame buffer (either FBO or regular 769 // back buffer) 770 GLenum GetBoundReadFrameBufferInternalFormat(); 771 GLenum GetBoundDrawFrameBufferInternalFormat(); 772 773 // Wrapper for CompressedTexImage2D commands. 774 error::Error DoCompressedTexImage2D( 775 GLenum target, 776 GLint level, 777 GLenum internal_format, 778 GLsizei width, 779 GLsizei height, 780 GLint border, 781 GLsizei image_size, 782 const void* data); 783 784 // Wrapper for CompressedTexSubImage2D. 785 void DoCompressedTexSubImage2D( 786 GLenum target, 787 GLint level, 788 GLint xoffset, 789 GLint yoffset, 790 GLsizei width, 791 GLsizei height, 792 GLenum format, 793 GLsizei imageSize, 794 const void * data); 795 796 // Wrapper for CopyTexImage2D. 797 void DoCopyTexImage2D( 798 GLenum target, 799 GLint level, 800 GLenum internal_format, 801 GLint x, 802 GLint y, 803 GLsizei width, 804 GLsizei height, 805 GLint border); 806 807 // Wrapper for SwapBuffers. 808 void DoSwapBuffers(); 809 810 // Wrapper for CopyTexSubImage2D. 811 void DoCopyTexSubImage2D( 812 GLenum target, 813 GLint level, 814 GLint xoffset, 815 GLint yoffset, 816 GLint x, 817 GLint y, 818 GLsizei width, 819 GLsizei height); 820 821 // Validation for TexImage2D commands. 822 bool ValidateTexImage2D( 823 const char* function_name, 824 GLenum target, 825 GLint level, 826 GLenum internal_format, 827 GLsizei width, 828 GLsizei height, 829 GLint border, 830 GLenum format, 831 GLenum type, 832 const void* pixels, 833 uint32 pixels_size); 834 835 // Wrapper for TexImage2D commands. 836 void DoTexImage2D( 837 GLenum target, 838 GLint level, 839 GLenum internal_format, 840 GLsizei width, 841 GLsizei height, 842 GLint border, 843 GLenum format, 844 GLenum type, 845 const void* pixels, 846 uint32 pixels_size); 847 848 // Validation for TexSubImage2D. 849 bool ValidateTexSubImage2D( 850 error::Error* error, 851 const char* function_name, 852 GLenum target, 853 GLint level, 854 GLint xoffset, 855 GLint yoffset, 856 GLsizei width, 857 GLsizei height, 858 GLenum format, 859 GLenum type, 860 const void * data); 861 862 // Wrapper for TexSubImage2D. 863 error::Error DoTexSubImage2D( 864 GLenum target, 865 GLint level, 866 GLint xoffset, 867 GLint yoffset, 868 GLsizei width, 869 GLsizei height, 870 GLenum format, 871 GLenum type, 872 const void * data); 873 874 // Extra validation for async tex(Sub)Image2D. 875 bool ValidateAsyncTransfer( 876 const char* function_name, 877 TextureRef* texture_ref, 878 GLenum target, 879 GLint level, 880 const void * data); 881 882 // Wrapper for TexImageIOSurface2DCHROMIUM. 883 void DoTexImageIOSurface2DCHROMIUM( 884 GLenum target, 885 GLsizei width, 886 GLsizei height, 887 GLuint io_surface_id, 888 GLuint plane); 889 890 void DoCopyTextureCHROMIUM( 891 GLenum target, 892 GLuint source_id, 893 GLuint target_id, 894 GLint level, 895 GLenum internal_format, 896 GLenum dest_type); 897 898 // Wrapper for TexStorage2DEXT. 899 void DoTexStorage2DEXT( 900 GLenum target, 901 GLint levels, 902 GLenum internal_format, 903 GLsizei width, 904 GLsizei height); 905 906 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); 907 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); 908 909 void DoBindTexImage2DCHROMIUM( 910 GLenum target, 911 GLint image_id); 912 void DoReleaseTexImage2DCHROMIUM( 913 GLenum target, 914 GLint image_id); 915 916 void DoTraceEndCHROMIUM(void); 917 918 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs); 919 920 // Creates a Program for the given program. 921 Program* CreateProgram( 922 GLuint client_id, GLuint service_id) { 923 return program_manager()->CreateProgram(client_id, service_id); 924 } 925 926 // Gets the program info for the given program. Returns NULL if none exists. 927 Program* GetProgram(GLuint client_id) { 928 return program_manager()->GetProgram(client_id); 929 } 930 931 #if defined(NDEBUG) 932 void LogClientServiceMapping( 933 const char* /* function_name */, 934 GLuint /* client_id */, 935 GLuint /* service_id */) { 936 } 937 template<typename T> 938 void LogClientServiceForInfo( 939 T* /* info */, GLuint /* client_id */, const char* /* function_name */) { 940 } 941 #else 942 void LogClientServiceMapping( 943 const char* function_name, GLuint client_id, GLuint service_id) { 944 if (service_logging_) { 945 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name 946 << ": client_id = " << client_id 947 << ", service_id = " << service_id; 948 } 949 } 950 template<typename T> 951 void LogClientServiceForInfo( 952 T* info, GLuint client_id, const char* function_name) { 953 if (info) { 954 LogClientServiceMapping(function_name, client_id, info->service_id()); 955 } 956 } 957 #endif 958 959 // Gets the program info for the given program. If it's not a program 960 // generates a GL error. Returns NULL if not program. 961 Program* GetProgramInfoNotShader( 962 GLuint client_id, const char* function_name) { 963 Program* program = GetProgram(client_id); 964 if (!program) { 965 if (GetShader(client_id)) { 966 LOCAL_SET_GL_ERROR( 967 GL_INVALID_OPERATION, function_name, "shader passed for program"); 968 } else { 969 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program"); 970 } 971 } 972 LogClientServiceForInfo(program, client_id, function_name); 973 return program; 974 } 975 976 977 // Creates a Shader for the given shader. 978 Shader* CreateShader( 979 GLuint client_id, 980 GLuint service_id, 981 GLenum shader_type) { 982 return shader_manager()->CreateShader( 983 client_id, service_id, shader_type); 984 } 985 986 // Gets the shader info for the given shader. Returns NULL if none exists. 987 Shader* GetShader(GLuint client_id) { 988 return shader_manager()->GetShader(client_id); 989 } 990 991 // Gets the shader info for the given shader. If it's not a shader generates a 992 // GL error. Returns NULL if not shader. 993 Shader* GetShaderInfoNotProgram( 994 GLuint client_id, const char* function_name) { 995 Shader* shader = GetShader(client_id); 996 if (!shader) { 997 if (GetProgram(client_id)) { 998 LOCAL_SET_GL_ERROR( 999 GL_INVALID_OPERATION, function_name, "program passed for shader"); 1000 } else { 1001 LOCAL_SET_GL_ERROR( 1002 GL_INVALID_VALUE, function_name, "unknown shader"); 1003 } 1004 } 1005 LogClientServiceForInfo(shader, client_id, function_name); 1006 return shader; 1007 } 1008 1009 // Creates a buffer info for the given buffer. 1010 void CreateBuffer(GLuint client_id, GLuint service_id) { 1011 return buffer_manager()->CreateBuffer(client_id, service_id); 1012 } 1013 1014 // Gets the buffer info for the given buffer. 1015 Buffer* GetBuffer(GLuint client_id) { 1016 Buffer* buffer = buffer_manager()->GetBuffer(client_id); 1017 return buffer; 1018 } 1019 1020 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used 1021 // on glDeleteBuffers so we can make sure the user does not try to render 1022 // with deleted buffers. 1023 void RemoveBuffer(GLuint client_id); 1024 1025 // Creates a framebuffer info for the given framebuffer. 1026 void CreateFramebuffer(GLuint client_id, GLuint service_id) { 1027 return framebuffer_manager()->CreateFramebuffer(client_id, service_id); 1028 } 1029 1030 // Gets the framebuffer info for the given framebuffer. 1031 Framebuffer* GetFramebuffer(GLuint client_id) { 1032 return framebuffer_manager()->GetFramebuffer(client_id); 1033 } 1034 1035 // Removes the framebuffer info for the given framebuffer. 1036 void RemoveFramebuffer(GLuint client_id) { 1037 framebuffer_manager()->RemoveFramebuffer(client_id); 1038 } 1039 1040 // Creates a renderbuffer info for the given renderbuffer. 1041 void CreateRenderbuffer(GLuint client_id, GLuint service_id) { 1042 return renderbuffer_manager()->CreateRenderbuffer( 1043 client_id, service_id); 1044 } 1045 1046 // Gets the renderbuffer info for the given renderbuffer. 1047 Renderbuffer* GetRenderbuffer(GLuint client_id) { 1048 return renderbuffer_manager()->GetRenderbuffer(client_id); 1049 } 1050 1051 // Removes the renderbuffer info for the given renderbuffer. 1052 void RemoveRenderbuffer(GLuint client_id) { 1053 renderbuffer_manager()->RemoveRenderbuffer(client_id); 1054 } 1055 1056 // Gets the vertex attrib manager for the given vertex array. 1057 VertexAttribManager* GetVertexAttribManager(GLuint client_id) { 1058 VertexAttribManager* info = 1059 vertex_array_manager()->GetVertexAttribManager(client_id); 1060 return info; 1061 } 1062 1063 // Removes the vertex attrib manager for the given vertex array. 1064 void RemoveVertexAttribManager(GLuint client_id) { 1065 vertex_array_manager()->RemoveVertexAttribManager(client_id); 1066 } 1067 1068 // Creates a vertex attrib manager for the given vertex array. 1069 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) { 1070 return vertex_array_manager()->CreateVertexAttribManager( 1071 client_id, service_id, group_->max_vertex_attribs()); 1072 } 1073 1074 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name); 1075 void DoBindUniformLocationCHROMIUM( 1076 GLuint client_id, GLint location, const char* name); 1077 1078 error::Error GetAttribLocationHelper( 1079 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 1080 const std::string& name_str); 1081 1082 error::Error GetUniformLocationHelper( 1083 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 1084 const std::string& name_str); 1085 1086 // Helper for glShaderSource. 1087 error::Error ShaderSourceHelper( 1088 GLuint client_id, const char* data, uint32 data_size); 1089 1090 // Clear any textures used by the current program. 1091 bool ClearUnclearedTextures(); 1092 1093 // Clear any uncleared level in texture. 1094 // Returns false if there was a generated GL error. 1095 bool ClearTexture(Texture* texture); 1096 1097 // Clears any uncleared attachments attached to the given frame buffer. 1098 // Returns false if there was a generated GL error. 1099 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); 1100 1101 // overridden from GLES2Decoder 1102 virtual bool ClearLevel(unsigned service_id, 1103 unsigned bind_target, 1104 unsigned target, 1105 int level, 1106 unsigned format, 1107 unsigned type, 1108 int width, 1109 int height, 1110 bool is_texture_immutable) OVERRIDE; 1111 1112 // Restore all GL state that affects clearing. 1113 void RestoreClearState(); 1114 1115 // Remembers the state of some capabilities. 1116 // Returns: true if glEnable/glDisable should actually be called. 1117 bool SetCapabilityState(GLenum cap, bool enabled); 1118 1119 // Check that the currently bound framebuffers are valid. 1120 // Generates GL error if not. 1121 bool CheckBoundFramebuffersValid(const char* func_name); 1122 1123 // Check if a framebuffer meets our requirements. 1124 bool CheckFramebufferValid( 1125 Framebuffer* framebuffer, 1126 GLenum target, 1127 const char* func_name); 1128 1129 // Checks if the current program exists and is valid. If not generates the 1130 // appropriate GL error. Returns true if the current program is in a usable 1131 // state. 1132 bool CheckCurrentProgram(const char* function_name); 1133 1134 // Checks if the current program exists and is valid and that location is not 1135 // -1. If the current program is not valid generates the appropriate GL 1136 // error. Returns true if the current program is in a usable state and 1137 // location is not -1. 1138 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); 1139 1140 // Gets the type of a uniform for a location in the current program. Sets GL 1141 // errors if the current program is not valid. Returns true if the current 1142 // program is valid and the location exists. Adjusts count so it 1143 // does not overflow the uniform. 1144 bool PrepForSetUniformByLocation( 1145 GLint fake_location, const char* function_name, 1146 const BaseUniformInfo& base_info, 1147 GLint* real_location, GLenum* type, GLsizei* count); 1148 1149 // Gets the service id for any simulated backbuffer fbo. 1150 GLuint GetBackbufferServiceId() const; 1151 1152 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv 1153 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written); 1154 1155 // Helper for glGetVertexAttrib 1156 void GetVertexAttribHelper( 1157 const VertexAttrib* attrib, GLenum pname, GLint* param); 1158 1159 // Wrapper for glCreateProgram 1160 bool CreateProgramHelper(GLuint client_id); 1161 1162 // Wrapper for glCreateShader 1163 bool CreateShaderHelper(GLenum type, GLuint client_id); 1164 1165 // Wrapper for glActiveTexture 1166 void DoActiveTexture(GLenum texture_unit); 1167 1168 // Wrapper for glAttachShader 1169 void DoAttachShader(GLuint client_program_id, GLint client_shader_id); 1170 1171 // Wrapper for glBindBuffer since we need to track the current targets. 1172 void DoBindBuffer(GLenum target, GLuint buffer); 1173 1174 // Wrapper for glBindFramebuffer since we need to track the current targets. 1175 void DoBindFramebuffer(GLenum target, GLuint framebuffer); 1176 1177 // Wrapper for glBindRenderbuffer since we need to track the current targets. 1178 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer); 1179 1180 // Wrapper for glBindTexture since we need to track the current targets. 1181 void DoBindTexture(GLenum target, GLuint texture); 1182 1183 // Wrapper for glBindVertexArrayOES 1184 void DoBindVertexArrayOES(GLuint array); 1185 void EmulateVertexArrayState(); 1186 1187 // Wrapper for glBlitFramebufferEXT. 1188 void DoBlitFramebufferEXT( 1189 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1190 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1191 GLbitfield mask, GLenum filter); 1192 1193 // Wrapper for glBufferSubData. 1194 void DoBufferSubData( 1195 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); 1196 1197 // Wrapper for glCheckFramebufferStatus 1198 GLenum DoCheckFramebufferStatus(GLenum target); 1199 1200 // Wrapper for glClear 1201 error::Error DoClear(GLbitfield mask); 1202 1203 // Wrappers for various state. 1204 void DoDepthRangef(GLclampf znear, GLclampf zfar); 1205 void DoSampleCoverage(GLclampf value, GLboolean invert); 1206 1207 // Wrapper for glCompileShader. 1208 void DoCompileShader(GLuint shader); 1209 1210 // Helper for DeleteSharedIdsCHROMIUM commands. 1211 void DoDeleteSharedIdsCHROMIUM( 1212 GLuint namespace_id, GLsizei n, const GLuint* ids); 1213 1214 // Wrapper for glDetachShader 1215 void DoDetachShader(GLuint client_program_id, GLint client_shader_id); 1216 1217 // Wrapper for glDisable 1218 void DoDisable(GLenum cap); 1219 1220 // Wrapper for glDisableVertexAttribArray. 1221 void DoDisableVertexAttribArray(GLuint index); 1222 1223 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined 1224 // attachments. 1225 void DoDiscardFramebufferEXT(GLenum target, 1226 GLsizei numAttachments, 1227 const GLenum* attachments); 1228 1229 // Wrapper for glEnable 1230 void DoEnable(GLenum cap); 1231 1232 // Wrapper for glEnableVertexAttribArray. 1233 void DoEnableVertexAttribArray(GLuint index); 1234 1235 // Wrapper for glFinish. 1236 void DoFinish(); 1237 1238 // Wrapper for glFlush. 1239 void DoFlush(); 1240 1241 // Wrapper for glFramebufferRenderbufffer. 1242 void DoFramebufferRenderbuffer( 1243 GLenum target, GLenum attachment, GLenum renderbuffertarget, 1244 GLuint renderbuffer); 1245 1246 // Wrapper for glFramebufferTexture2D. 1247 void DoFramebufferTexture2D( 1248 GLenum target, GLenum attachment, GLenum textarget, GLuint texture, 1249 GLint level); 1250 1251 // Wrapper for glFramebufferTexture2DMultisampleEXT. 1252 void DoFramebufferTexture2DMultisample( 1253 GLenum target, GLenum attachment, GLenum textarget, 1254 GLuint texture, GLint level, GLsizei samples); 1255 1256 // Common implementation for both DoFramebufferTexture2D wrappers. 1257 void DoFramebufferTexture2DCommon(const char* name, 1258 GLenum target, GLenum attachment, GLenum textarget, 1259 GLuint texture, GLint level, GLsizei samples); 1260 1261 // Wrapper for glGenerateMipmap 1262 void DoGenerateMipmap(GLenum target); 1263 1264 // Helper for GenSharedIdsCHROMIUM commands. 1265 void DoGenSharedIdsCHROMIUM( 1266 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); 1267 1268 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname 1269 // to account for different pname values defined in different extension 1270 // variants. 1271 GLenum AdjustGetPname(GLenum pname); 1272 1273 // Wrapper for DoGetBooleanv. 1274 void DoGetBooleanv(GLenum pname, GLboolean* params); 1275 1276 // Wrapper for DoGetFloatv. 1277 void DoGetFloatv(GLenum pname, GLfloat* params); 1278 1279 // Wrapper for glGetFramebufferAttachmentParameteriv. 1280 void DoGetFramebufferAttachmentParameteriv( 1281 GLenum target, GLenum attachment, GLenum pname, GLint* params); 1282 1283 // Wrapper for glGetIntegerv. 1284 void DoGetIntegerv(GLenum pname, GLint* params); 1285 1286 // Gets the max value in a range in a buffer. 1287 GLuint DoGetMaxValueInBufferCHROMIUM( 1288 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); 1289 1290 // Wrapper for glGetBufferParameteriv. 1291 void DoGetBufferParameteriv( 1292 GLenum target, GLenum pname, GLint* params); 1293 1294 // Wrapper for glGetProgramiv. 1295 void DoGetProgramiv( 1296 GLuint program_id, GLenum pname, GLint* params); 1297 1298 // Wrapper for glRenderbufferParameteriv. 1299 void DoGetRenderbufferParameteriv( 1300 GLenum target, GLenum pname, GLint* params); 1301 1302 // Wrapper for glGetShaderiv 1303 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params); 1304 1305 // Wrappers for glGetVertexAttrib. 1306 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); 1307 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params); 1308 1309 // Wrappers for glIsXXX functions. 1310 bool DoIsEnabled(GLenum cap); 1311 bool DoIsBuffer(GLuint client_id); 1312 bool DoIsFramebuffer(GLuint client_id); 1313 bool DoIsProgram(GLuint client_id); 1314 bool DoIsRenderbuffer(GLuint client_id); 1315 bool DoIsShader(GLuint client_id); 1316 bool DoIsTexture(GLuint client_id); 1317 bool DoIsVertexArrayOES(GLuint client_id); 1318 1319 // Wrapper for glLinkProgram 1320 void DoLinkProgram(GLuint program); 1321 1322 // Helper for RegisterSharedIdsCHROMIUM. 1323 void DoRegisterSharedIdsCHROMIUM( 1324 GLuint namespace_id, GLsizei n, const GLuint* ids); 1325 1326 // Wrapper for glRenderbufferStorage. 1327 void DoRenderbufferStorage( 1328 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 1329 1330 // Wrapper for glRenderbufferStorageMultisampleEXT. 1331 void DoRenderbufferStorageMultisample( 1332 GLenum target, GLsizei samples, GLenum internalformat, 1333 GLsizei width, GLsizei height); 1334 1335 // Wrapper for glReleaseShaderCompiler. 1336 void DoReleaseShaderCompiler() { } 1337 1338 // Wrappers for glTexParameter functions. 1339 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); 1340 void DoTexParameteri(GLenum target, GLenum pname, GLint param); 1341 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); 1342 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); 1343 1344 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 1345 // spec only these 2 functions can be used to set sampler uniforms. 1346 void DoUniform1i(GLint fake_location, GLint v0); 1347 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value); 1348 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value); 1349 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value); 1350 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value); 1351 1352 // Wrappers for glUniformfv because some drivers don't correctly accept 1353 // bool uniforms. 1354 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value); 1355 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value); 1356 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value); 1357 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value); 1358 1359 void DoUniformMatrix2fv( 1360 GLint fake_location, GLsizei count, GLboolean transpose, 1361 const GLfloat* value); 1362 void DoUniformMatrix3fv( 1363 GLint fake_location, GLsizei count, GLboolean transpose, 1364 const GLfloat* value); 1365 void DoUniformMatrix4fv( 1366 GLint fake_location, GLsizei count, GLboolean transpose, 1367 const GLfloat* value); 1368 1369 bool SetVertexAttribValue( 1370 const char* function_name, GLuint index, const GLfloat* value); 1371 1372 // Wrappers for glVertexAttrib?? 1373 void DoVertexAttrib1f(GLuint index, GLfloat v0); 1374 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1); 1375 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2); 1376 void DoVertexAttrib4f( 1377 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 1378 void DoVertexAttrib1fv(GLuint index, const GLfloat *v); 1379 void DoVertexAttrib2fv(GLuint index, const GLfloat *v); 1380 void DoVertexAttrib3fv(GLuint index, const GLfloat *v); 1381 void DoVertexAttrib4fv(GLuint index, const GLfloat *v); 1382 1383 // Wrapper for glViewport 1384 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); 1385 1386 // Wrapper for glUseProgram 1387 void DoUseProgram(GLuint program); 1388 1389 // Wrapper for glValidateProgram. 1390 void DoValidateProgram(GLuint program_client_id); 1391 1392 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker); 1393 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group); 1394 void DoPopGroupMarkerEXT(void); 1395 1396 // Gets the number of values that will be returned by glGetXXX. Returns 1397 // false if pname is unknown. 1398 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); 1399 1400 // Checks if the current program and vertex attributes are valid for drawing. 1401 bool IsDrawValid( 1402 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount); 1403 1404 // Returns true if successful, simulated will be true if attrib0 was 1405 // simulated. 1406 bool SimulateAttrib0( 1407 const char* function_name, GLuint max_vertex_accessed, bool* simulated); 1408 void RestoreStateForAttrib(GLuint attrib); 1409 1410 // If texture is a stream texture, this will update the stream to the newest 1411 // buffer and bind the texture implicitly. 1412 void UpdateStreamTextureIfNeeded(Texture* texture, GLuint texture_unit_index); 1413 1414 // If an image is bound to texture, this will call Will/DidUseTexImage 1415 // if needed. 1416 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget); 1417 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget); 1418 1419 // Returns false if textures were replaced. 1420 bool PrepareTexturesForRender(); 1421 void RestoreStateForTextures(); 1422 1423 // Returns true if GL_FIXED attribs were simulated. 1424 bool SimulateFixedAttribs( 1425 const char* function_name, 1426 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount); 1427 void RestoreStateForSimulatedFixedAttribs(); 1428 1429 // Handle DrawArrays and DrawElements for both instanced and non-instanced 1430 // cases (primcount is 0 for non-instanced). 1431 error::Error DoDrawArrays( 1432 const char* function_name, 1433 bool instanced, GLenum mode, GLint first, GLsizei count, 1434 GLsizei primcount); 1435 error::Error DoDrawElements( 1436 const char* function_name, 1437 bool instanced, GLenum mode, GLsizei count, GLenum type, 1438 int32 offset, GLsizei primcount); 1439 1440 // Gets the texture id for a given target. 1441 TextureRef* GetTextureInfoForTarget(GLenum target) { 1442 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 1443 TextureRef* texture = NULL; 1444 switch (target) { 1445 case GL_TEXTURE_2D: 1446 texture = unit.bound_texture_2d.get(); 1447 break; 1448 case GL_TEXTURE_CUBE_MAP: 1449 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1450 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1451 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1452 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1453 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1454 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1455 texture = unit.bound_texture_cube_map.get(); 1456 break; 1457 case GL_TEXTURE_EXTERNAL_OES: 1458 texture = unit.bound_texture_external_oes.get(); 1459 break; 1460 case GL_TEXTURE_RECTANGLE_ARB: 1461 texture = unit.bound_texture_rectangle_arb.get(); 1462 break; 1463 default: 1464 NOTREACHED(); 1465 return NULL; 1466 } 1467 return texture; 1468 } 1469 1470 TextureRef* GetTextureInfoForTargetUnlessDefault( 1471 GLenum target) { 1472 TextureRef* texture = GetTextureInfoForTarget(target); 1473 if (!texture) 1474 return NULL; 1475 if (texture == texture_manager()->GetDefaultTextureInfo(target)) 1476 return NULL; 1477 return texture; 1478 } 1479 1480 GLenum GetBindTargetForSamplerType(GLenum type) { 1481 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || 1482 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB); 1483 switch (type) { 1484 case GL_SAMPLER_2D: 1485 return GL_TEXTURE_2D; 1486 case GL_SAMPLER_CUBE: 1487 return GL_TEXTURE_CUBE_MAP; 1488 case GL_SAMPLER_EXTERNAL_OES: 1489 return GL_TEXTURE_EXTERNAL_OES; 1490 case GL_SAMPLER_2D_RECT_ARB: 1491 return GL_TEXTURE_RECTANGLE_ARB; 1492 } 1493 1494 NOTREACHED(); 1495 return 0; 1496 } 1497 1498 // Gets the framebuffer info for a particular target. 1499 Framebuffer* GetFramebufferInfoForTarget(GLenum target) { 1500 Framebuffer* framebuffer = NULL; 1501 switch (target) { 1502 case GL_FRAMEBUFFER: 1503 case GL_DRAW_FRAMEBUFFER_EXT: 1504 framebuffer = state_.bound_draw_framebuffer.get(); 1505 break; 1506 case GL_READ_FRAMEBUFFER_EXT: 1507 framebuffer = state_.bound_read_framebuffer.get(); 1508 break; 1509 default: 1510 NOTREACHED(); 1511 break; 1512 } 1513 return framebuffer; 1514 } 1515 1516 Renderbuffer* GetRenderbufferInfoForTarget( 1517 GLenum target) { 1518 Renderbuffer* renderbuffer = NULL; 1519 switch (target) { 1520 case GL_RENDERBUFFER: 1521 renderbuffer = state_.bound_renderbuffer.get(); 1522 break; 1523 default: 1524 NOTREACHED(); 1525 break; 1526 } 1527 return renderbuffer; 1528 } 1529 1530 // Validates the program and location for a glGetUniform call and returns 1531 // a SizeResult setup to receive the result. Returns true if glGetUniform 1532 // should be called. 1533 bool GetUniformSetup( 1534 GLuint program, GLint fake_location, 1535 uint32 shm_id, uint32 shm_offset, 1536 error::Error* error, GLint* real_location, GLuint* service_id, 1537 void** result, GLenum* result_type); 1538 1539 // Computes the estimated memory used for the backbuffer and passes it to 1540 // the tracing system. 1541 size_t GetBackbufferMemoryTotal(); 1542 1543 virtual bool WasContextLost() OVERRIDE; 1544 virtual bool WasContextLostByRobustnessExtension() OVERRIDE; 1545 virtual void LoseContext(uint32 reset_status) OVERRIDE; 1546 1547 #if defined(OS_MACOSX) 1548 void ReleaseIOSurfaceForTexture(GLuint texture_id); 1549 #endif 1550 1551 // Validates the combination of texture parameters. For example validates that 1552 // for a given format the specific type, level and targets are valid. 1553 // Synthesizes the correct GL error if invalid. Returns true if valid. 1554 bool ValidateTextureParameters( 1555 const char* function_name, 1556 GLenum target, GLenum format, GLenum type, GLint level); 1557 1558 bool ValidateCompressedTexDimensions( 1559 const char* function_name, 1560 GLint level, GLsizei width, GLsizei height, GLenum format); 1561 bool ValidateCompressedTexFuncData( 1562 const char* function_name, 1563 GLsizei width, GLsizei height, GLenum format, size_t size); 1564 bool ValidateCompressedTexSubDimensions( 1565 const char* function_name, 1566 GLenum target, GLint level, GLint xoffset, GLint yoffset, 1567 GLsizei width, GLsizei height, GLenum format, 1568 Texture* texture); 1569 1570 void RenderWarning(const char* filename, int line, const std::string& msg); 1571 void PerformanceWarning( 1572 const char* filename, int line, const std::string& msg); 1573 1574 const FeatureInfo::FeatureFlags& features() const { 1575 return feature_info_->feature_flags(); 1576 } 1577 1578 const FeatureInfo::Workarounds& workarounds() const { 1579 return feature_info_->workarounds(); 1580 } 1581 1582 bool ShouldDeferDraws() { 1583 return !offscreen_target_frame_buffer_.get() && 1584 state_.bound_draw_framebuffer.get() == NULL && 1585 surface_->DeferDraws(); 1586 } 1587 1588 bool ShouldDeferReads() { 1589 return !offscreen_target_frame_buffer_.get() && 1590 state_.bound_read_framebuffer.get() == NULL && 1591 surface_->DeferDraws(); 1592 } 1593 1594 void ProcessPendingReadPixels(); 1595 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); 1596 1597 // Generate a member function prototype for each command in an automated and 1598 // typesafe way. 1599 #define GLES2_CMD_OP(name) \ 1600 Error Handle ## name( \ 1601 uint32 immediate_data_size, \ 1602 const cmds::name& args); \ 1603 1604 GLES2_COMMAND_LIST(GLES2_CMD_OP) 1605 1606 #undef GLES2_CMD_OP 1607 1608 // The GL context this decoder renders to on behalf of the client. 1609 scoped_refptr<gfx::GLSurface> surface_; 1610 scoped_refptr<gfx::GLContext> context_; 1611 1612 // The ContextGroup for this decoder uses to track resources. 1613 scoped_refptr<ContextGroup> group_; 1614 1615 DebugMarkerManager debug_marker_manager_; 1616 Logger logger_; 1617 1618 // All the state for this context. 1619 ContextState state_; 1620 1621 // Current width and height of the offscreen frame buffer. 1622 gfx::Size offscreen_size_; 1623 1624 // Util to help with GL. 1625 GLES2Util util_; 1626 1627 // unpack flip y as last set by glPixelStorei 1628 bool unpack_flip_y_; 1629 1630 // unpack (un)premultiply alpha as last set by glPixelStorei 1631 bool unpack_premultiply_alpha_; 1632 bool unpack_unpremultiply_alpha_; 1633 1634 // Default vertex attribs manager, used when no VAOs are bound. 1635 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_; 1636 1637 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not). 1638 GLuint attrib_0_buffer_id_; 1639 1640 // The value currently in attrib_0. 1641 Vec4 attrib_0_value_; 1642 1643 // Whether or not the attrib_0 buffer holds the attrib_0_value. 1644 bool attrib_0_buffer_matches_value_; 1645 1646 // The size of attrib 0. 1647 GLsizei attrib_0_size_; 1648 1649 // The buffer used to simulate GL_FIXED attribs. 1650 GLuint fixed_attrib_buffer_id_; 1651 1652 // The size of fiixed attrib buffer. 1653 GLsizei fixed_attrib_buffer_size_; 1654 1655 // state saved for clearing so we can clear render buffers and then 1656 // restore to these values. 1657 bool clear_state_dirty_; 1658 1659 // The offscreen frame buffer that the client renders to. With EGL, the 1660 // depth and stencil buffers are separate. With regular GL there is a single 1661 // packed depth stencil buffer in offscreen_target_depth_render_buffer_. 1662 // offscreen_target_stencil_render_buffer_ is unused. 1663 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_; 1664 scoped_ptr<BackTexture> offscreen_target_color_texture_; 1665 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_; 1666 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_; 1667 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_; 1668 GLenum offscreen_target_color_format_; 1669 GLenum offscreen_target_depth_format_; 1670 GLenum offscreen_target_stencil_format_; 1671 GLsizei offscreen_target_samples_; 1672 GLboolean offscreen_target_buffer_preserved_; 1673 1674 // The copy that is saved when SwapBuffers is called. 1675 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_; 1676 scoped_ptr<BackTexture> offscreen_saved_color_texture_; 1677 scoped_refptr<TextureRef> 1678 offscreen_saved_color_texture_info_; 1679 1680 // The copy that is used as the destination for multi-sample resolves. 1681 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_; 1682 scoped_ptr<BackTexture> offscreen_resolved_color_texture_; 1683 GLenum offscreen_saved_color_format_; 1684 1685 scoped_ptr<QueryManager> query_manager_; 1686 1687 scoped_ptr<VertexArrayManager> vertex_array_manager_; 1688 1689 base::Callback<void(gfx::Size, float)> resize_callback_; 1690 1691 WaitSyncPointCallback wait_sync_point_callback_; 1692 1693 ShaderCacheCallback shader_cache_callback_; 1694 1695 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_; 1696 1697 // The format of the back buffer_ 1698 GLenum back_buffer_color_format_; 1699 bool back_buffer_has_depth_; 1700 bool back_buffer_has_stencil_; 1701 1702 // Backbuffer attachments that are currently undefined. 1703 uint32 backbuffer_needs_clear_bits_; 1704 1705 bool teximage2d_faster_than_texsubimage2d_; 1706 1707 // The current decoder error. 1708 error::Error current_decoder_error_; 1709 1710 bool use_shader_translator_; 1711 scoped_refptr<ShaderTranslator> vertex_translator_; 1712 scoped_refptr<ShaderTranslator> fragment_translator_; 1713 1714 DisallowedFeatures disallowed_features_; 1715 1716 // Cached from ContextGroup 1717 const Validators* validators_; 1718 scoped_refptr<FeatureInfo> feature_info_; 1719 1720 // This indicates all the following texSubImage2D calls that are part of the 1721 // failed texImage2D call should be ignored. 1722 bool tex_image_2d_failed_; 1723 1724 int frame_number_; 1725 1726 bool has_robustness_extension_; 1727 GLenum reset_status_; 1728 bool reset_by_robustness_extension_; 1729 1730 // These flags are used to override the state of the shared feature_info_ 1731 // member. Because the same FeatureInfo instance may be shared among many 1732 // contexts, the assumptions on the availablity of extensions in WebGL 1733 // contexts may be broken. These flags override the shared state to preserve 1734 // WebGL semantics. 1735 bool force_webgl_glsl_validation_; 1736 bool derivatives_explicitly_enabled_; 1737 bool frag_depth_explicitly_enabled_; 1738 bool draw_buffers_explicitly_enabled_; 1739 1740 bool compile_shader_always_succeeds_; 1741 1742 // Log extra info. 1743 bool service_logging_; 1744 1745 #if defined(OS_MACOSX) 1746 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap; 1747 TextureToIOSurfaceMap texture_to_io_surface_map_; 1748 #endif 1749 1750 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; 1751 1752 // Cached values of the currently assigned viewport dimensions. 1753 GLsizei viewport_max_width_; 1754 GLsizei viewport_max_height_; 1755 1756 // Command buffer stats. 1757 int texture_upload_count_; 1758 base::TimeDelta total_texture_upload_time_; 1759 base::TimeDelta total_processing_commands_time_; 1760 1761 scoped_ptr<GPUTracer> gpu_tracer_; 1762 1763 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; 1764 1765 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); 1766 }; 1767 1768 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( 1769 const char* function_name, GLES2DecoderImpl* decoder) 1770 : function_name_(function_name), 1771 decoder_(decoder) { 1772 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(), 1773 function_name_); 1774 } 1775 1776 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { 1777 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_); 1778 } 1779 1780 ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, 1781 GLuint id) 1782 : decoder_(decoder) { 1783 ScopedGLErrorSuppressor suppressor( 1784 "ScopedTexture2DBinder::ctor", decoder_); 1785 1786 // TODO(apatrick): Check if there are any other states that need to be reset 1787 // before binding a new texture. 1788 glActiveTexture(GL_TEXTURE0); 1789 glBindTexture(GL_TEXTURE_2D, id); 1790 } 1791 1792 ScopedTexture2DBinder::~ScopedTexture2DBinder() { 1793 ScopedGLErrorSuppressor suppressor( 1794 "ScopedTexture2DBinder::dtor", decoder_); 1795 decoder_->RestoreCurrentTexture2DBindings(); 1796 } 1797 1798 ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, 1799 GLuint id) 1800 : decoder_(decoder) { 1801 ScopedGLErrorSuppressor suppressor( 1802 "ScopedRenderBufferBinder::ctor", decoder_); 1803 glBindRenderbufferEXT(GL_RENDERBUFFER, id); 1804 } 1805 1806 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { 1807 ScopedGLErrorSuppressor suppressor( 1808 "ScopedRenderBufferBinder::dtor", decoder_); 1809 decoder_->RestoreCurrentRenderbufferBindings(); 1810 } 1811 1812 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, 1813 GLuint id) 1814 : decoder_(decoder) { 1815 ScopedGLErrorSuppressor suppressor( 1816 "ScopedFrameBufferBinder::ctor", decoder_); 1817 glBindFramebufferEXT(GL_FRAMEBUFFER, id); 1818 decoder->OnFboChanged(); 1819 } 1820 1821 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { 1822 ScopedGLErrorSuppressor suppressor( 1823 "ScopedFrameBufferBinder::dtor", decoder_); 1824 decoder_->RestoreCurrentFramebufferBindings(); 1825 } 1826 1827 ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( 1828 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) 1829 : decoder_(decoder) { 1830 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() && 1831 decoder_->IsOffscreenBufferMultisampled() && 1832 (!decoder_->state_.bound_read_framebuffer.get() || 1833 enforce_internal_framebuffer)); 1834 if (!resolve_and_bind_) 1835 return; 1836 1837 ScopedGLErrorSuppressor suppressor( 1838 "ScopedResolvedFrameBufferBinder::ctor", decoder_); 1839 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 1840 decoder_->offscreen_target_frame_buffer_->id()); 1841 GLuint targetid; 1842 if (internal) { 1843 if (!decoder_->offscreen_resolved_frame_buffer_.get()) { 1844 decoder_->offscreen_resolved_frame_buffer_.reset( 1845 new BackFramebuffer(decoder_)); 1846 decoder_->offscreen_resolved_frame_buffer_->Create(); 1847 decoder_->offscreen_resolved_color_texture_.reset( 1848 new BackTexture(decoder_)); 1849 decoder_->offscreen_resolved_color_texture_->Create(); 1850 1851 DCHECK(decoder_->offscreen_saved_color_format_); 1852 decoder_->offscreen_resolved_color_texture_->AllocateStorage( 1853 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_, 1854 false); 1855 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture( 1856 decoder_->offscreen_resolved_color_texture_.get()); 1857 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() != 1858 GL_FRAMEBUFFER_COMPLETE) { 1859 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed " 1860 << "because offscreen resolved FBO was incomplete."; 1861 return; 1862 } 1863 } 1864 targetid = decoder_->offscreen_resolved_frame_buffer_->id(); 1865 } else { 1866 targetid = decoder_->offscreen_saved_frame_buffer_->id(); 1867 } 1868 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid); 1869 const int width = decoder_->offscreen_size_.width(); 1870 const int height = decoder_->offscreen_size_.height(); 1871 glDisable(GL_SCISSOR_TEST); 1872 if (GLES2Decoder::IsAngle()) { 1873 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, 1874 GL_COLOR_BUFFER_BIT, GL_NEAREST); 1875 } else { 1876 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, 1877 GL_COLOR_BUFFER_BIT, GL_NEAREST); 1878 } 1879 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); 1880 } 1881 1882 ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { 1883 if (!resolve_and_bind_) 1884 return; 1885 1886 ScopedGLErrorSuppressor suppressor( 1887 "ScopedResolvedFrameBufferBinder::dtor", decoder_); 1888 decoder_->RestoreCurrentFramebufferBindings(); 1889 if (decoder_->state_.enable_flags.scissor_test) { 1890 glEnable(GL_SCISSOR_TEST); 1891 } 1892 } 1893 1894 ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder) 1895 : decoder_(decoder), 1896 begin_time_(base::TimeTicks::HighResNow()) { 1897 } 1898 1899 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { 1900 decoder_->texture_upload_count_++; 1901 decoder_->total_texture_upload_time_ += 1902 base::TimeTicks::HighResNow() - begin_time_; 1903 } 1904 1905 BackTexture::BackTexture(GLES2DecoderImpl* decoder) 1906 : decoder_(decoder), 1907 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged), 1908 bytes_allocated_(0), 1909 id_(0) { 1910 } 1911 1912 BackTexture::~BackTexture() { 1913 // This does not destroy the render texture because that would require that 1914 // the associated GL context was current. Just check that it was explicitly 1915 // destroyed. 1916 DCHECK_EQ(id_, 0u); 1917 } 1918 1919 void BackTexture::Create() { 1920 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_); 1921 Destroy(); 1922 glGenTextures(1, &id_); 1923 ScopedTexture2DBinder binder(decoder_, id_); 1924 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1925 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1926 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1927 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1928 1929 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is 1930 // never called on an offscreen context, no data will ever be uploaded to the 1931 // saved offscreen color texture (it is deferred until to when SwapBuffers 1932 // is called). My idea is that some nvidia drivers might have a bug where 1933 // deleting a texture that has never been populated might cause a 1934 // crash. 1935 glTexImage2D( 1936 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 1937 1938 bytes_allocated_ = 16u * 16u * 4u; 1939 memory_tracker_.TrackMemAlloc(bytes_allocated_); 1940 } 1941 1942 bool BackTexture::AllocateStorage( 1943 const gfx::Size& size, GLenum format, bool zero) { 1944 DCHECK_NE(id_, 0u); 1945 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_); 1946 ScopedTexture2DBinder binder(decoder_, id_); 1947 uint32 image_size = 0; 1948 GLES2Util::ComputeImageDataSizes( 1949 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size, 1950 NULL, NULL); 1951 1952 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) { 1953 return false; 1954 } 1955 1956 scoped_ptr<char[]> zero_data; 1957 if (zero) { 1958 zero_data.reset(new char[image_size]); 1959 memset(zero_data.get(), 0, image_size); 1960 } 1961 1962 glTexImage2D(GL_TEXTURE_2D, 1963 0, // mip level 1964 format, 1965 size.width(), 1966 size.height(), 1967 0, // border 1968 format, 1969 GL_UNSIGNED_BYTE, 1970 zero_data.get()); 1971 1972 size_ = size; 1973 1974 bool success = glGetError() == GL_NO_ERROR; 1975 if (success) { 1976 memory_tracker_.TrackMemFree(bytes_allocated_); 1977 bytes_allocated_ = image_size; 1978 memory_tracker_.TrackMemAlloc(bytes_allocated_); 1979 } 1980 return success; 1981 } 1982 1983 void BackTexture::Copy(const gfx::Size& size, GLenum format) { 1984 DCHECK_NE(id_, 0u); 1985 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_); 1986 ScopedTexture2DBinder binder(decoder_, id_); 1987 glCopyTexImage2D(GL_TEXTURE_2D, 1988 0, // level 1989 format, 1990 0, 0, 1991 size.width(), 1992 size.height(), 1993 0); // border 1994 } 1995 1996 void BackTexture::Destroy() { 1997 if (id_ != 0) { 1998 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_); 1999 glDeleteTextures(1, &id_); 2000 id_ = 0; 2001 } 2002 memory_tracker_.TrackMemFree(bytes_allocated_); 2003 bytes_allocated_ = 0; 2004 } 2005 2006 void BackTexture::Invalidate() { 2007 id_ = 0; 2008 } 2009 2010 BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder) 2011 : decoder_(decoder), 2012 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged), 2013 bytes_allocated_(0), 2014 id_(0) { 2015 } 2016 2017 BackRenderbuffer::~BackRenderbuffer() { 2018 // This does not destroy the render buffer because that would require that 2019 // the associated GL context was current. Just check that it was explicitly 2020 // destroyed. 2021 DCHECK_EQ(id_, 0u); 2022 } 2023 2024 void BackRenderbuffer::Create() { 2025 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_); 2026 Destroy(); 2027 glGenRenderbuffersEXT(1, &id_); 2028 } 2029 2030 bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format, 2031 GLsizei samples) { 2032 ScopedGLErrorSuppressor suppressor( 2033 "BackRenderbuffer::AllocateStorage", decoder_); 2034 ScopedRenderBufferBinder binder(decoder_, id_); 2035 2036 uint32 estimated_size = 0; 2037 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize( 2038 size.width(), size.height(), samples, format, &estimated_size)) { 2039 return false; 2040 } 2041 2042 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) { 2043 return false; 2044 } 2045 2046 if (samples <= 1) { 2047 glRenderbufferStorageEXT(GL_RENDERBUFFER, 2048 format, 2049 size.width(), 2050 size.height()); 2051 } else { 2052 if (GLES2Decoder::IsAngle()) { 2053 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2054 samples, 2055 format, 2056 size.width(), 2057 size.height()); 2058 } else { 2059 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 2060 samples, 2061 format, 2062 size.width(), 2063 size.height()); 2064 } 2065 } 2066 bool success = glGetError() == GL_NO_ERROR; 2067 if (success) { 2068 memory_tracker_.TrackMemFree(bytes_allocated_); 2069 bytes_allocated_ = estimated_size; 2070 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2071 } 2072 return success; 2073 } 2074 2075 void BackRenderbuffer::Destroy() { 2076 if (id_ != 0) { 2077 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_); 2078 glDeleteRenderbuffersEXT(1, &id_); 2079 id_ = 0; 2080 } 2081 memory_tracker_.TrackMemFree(bytes_allocated_); 2082 bytes_allocated_ = 0; 2083 } 2084 2085 void BackRenderbuffer::Invalidate() { 2086 id_ = 0; 2087 } 2088 2089 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder) 2090 : decoder_(decoder), 2091 id_(0) { 2092 } 2093 2094 BackFramebuffer::~BackFramebuffer() { 2095 // This does not destroy the frame buffer because that would require that 2096 // the associated GL context was current. Just check that it was explicitly 2097 // destroyed. 2098 DCHECK_EQ(id_, 0u); 2099 } 2100 2101 void BackFramebuffer::Create() { 2102 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_); 2103 Destroy(); 2104 glGenFramebuffersEXT(1, &id_); 2105 } 2106 2107 void BackFramebuffer::AttachRenderTexture(BackTexture* texture) { 2108 DCHECK_NE(id_, 0u); 2109 ScopedGLErrorSuppressor suppressor( 2110 "BackFramebuffer::AttachRenderTexture", decoder_); 2111 ScopedFrameBufferBinder binder(decoder_, id_); 2112 GLuint attach_id = texture ? texture->id() : 0; 2113 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 2114 GL_COLOR_ATTACHMENT0, 2115 GL_TEXTURE_2D, 2116 attach_id, 2117 0); 2118 } 2119 2120 void BackFramebuffer::AttachRenderBuffer(GLenum target, 2121 BackRenderbuffer* render_buffer) { 2122 DCHECK_NE(id_, 0u); 2123 ScopedGLErrorSuppressor suppressor( 2124 "BackFramebuffer::AttachRenderBuffer", decoder_); 2125 ScopedFrameBufferBinder binder(decoder_, id_); 2126 GLuint attach_id = render_buffer ? render_buffer->id() : 0; 2127 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, 2128 target, 2129 GL_RENDERBUFFER, 2130 attach_id); 2131 } 2132 2133 void BackFramebuffer::Destroy() { 2134 if (id_ != 0) { 2135 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_); 2136 glDeleteFramebuffersEXT(1, &id_); 2137 id_ = 0; 2138 } 2139 } 2140 2141 void BackFramebuffer::Invalidate() { 2142 id_ = 0; 2143 } 2144 2145 GLenum BackFramebuffer::CheckStatus() { 2146 DCHECK_NE(id_, 0u); 2147 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_); 2148 ScopedFrameBufferBinder binder(decoder_, id_); 2149 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 2150 } 2151 2152 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { 2153 return new GLES2DecoderImpl(group); 2154 } 2155 2156 GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) 2157 : GLES2Decoder(), 2158 group_(group), 2159 logger_(&debug_marker_manager_), 2160 state_(group_->feature_info(), &logger_), 2161 unpack_flip_y_(false), 2162 unpack_premultiply_alpha_(false), 2163 unpack_unpremultiply_alpha_(false), 2164 attrib_0_buffer_id_(0), 2165 attrib_0_buffer_matches_value_(true), 2166 attrib_0_size_(0), 2167 fixed_attrib_buffer_id_(0), 2168 fixed_attrib_buffer_size_(0), 2169 clear_state_dirty_(true), 2170 offscreen_target_color_format_(0), 2171 offscreen_target_depth_format_(0), 2172 offscreen_target_stencil_format_(0), 2173 offscreen_target_samples_(0), 2174 offscreen_target_buffer_preserved_(true), 2175 offscreen_saved_color_format_(0), 2176 back_buffer_color_format_(0), 2177 back_buffer_has_depth_(false), 2178 back_buffer_has_stencil_(false), 2179 backbuffer_needs_clear_bits_(0), 2180 teximage2d_faster_than_texsubimage2d_(true), 2181 current_decoder_error_(error::kNoError), 2182 use_shader_translator_(true), 2183 validators_(group_->feature_info()->validators()), 2184 feature_info_(group_->feature_info()), 2185 tex_image_2d_failed_(false), 2186 frame_number_(0), 2187 has_robustness_extension_(false), 2188 reset_status_(GL_NO_ERROR), 2189 reset_by_robustness_extension_(false), 2190 force_webgl_glsl_validation_(false), 2191 derivatives_explicitly_enabled_(false), 2192 frag_depth_explicitly_enabled_(false), 2193 draw_buffers_explicitly_enabled_(false), 2194 compile_shader_always_succeeds_(false), 2195 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch( 2196 switches::kEnableGPUServiceLoggingGPU)), 2197 viewport_max_width_(0), 2198 viewport_max_height_(0), 2199 texture_upload_count_(0) { 2200 DCHECK(group); 2201 2202 attrib_0_value_.v[0] = 0.0f; 2203 attrib_0_value_.v[1] = 0.0f; 2204 attrib_0_value_.v[2] = 0.0f; 2205 attrib_0_value_.v[3] = 1.0f; 2206 2207 // The shader translator is used for WebGL even when running on EGL 2208 // because additional restrictions are needed (like only enabling 2209 // GL_OES_standard_derivatives on demand). It is used for the unit 2210 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes 2211 // the empty string to CompileShader and this is not a valid shader. 2212 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL || 2213 CommandLine::ForCurrentProcess()->HasSwitch( 2214 switches::kDisableGLSLTranslator)) { 2215 use_shader_translator_ = false; 2216 } 2217 2218 // TODO(gman): Consider setting this based on GPU and/or driver. 2219 if (IsAngle()) { 2220 teximage2d_faster_than_texsubimage2d_ = false; 2221 } 2222 } 2223 2224 GLES2DecoderImpl::~GLES2DecoderImpl() { 2225 } 2226 2227 bool GLES2DecoderImpl::Initialize( 2228 const scoped_refptr<gfx::GLSurface>& surface, 2229 const scoped_refptr<gfx::GLContext>& context, 2230 bool offscreen, 2231 const gfx::Size& size, 2232 const DisallowedFeatures& disallowed_features, 2233 const char* allowed_extensions, 2234 const std::vector<int32>& attribs) { 2235 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); 2236 DCHECK(context->IsCurrent(surface.get())); 2237 DCHECK(!context_.get()); 2238 2239 set_initialized(); 2240 gpu_tracer_ = GPUTracer::Create(); 2241 2242 if (CommandLine::ForCurrentProcess()->HasSwitch( 2243 switches::kEnableGPUDebugging)) { 2244 set_debug(true); 2245 } 2246 2247 if (CommandLine::ForCurrentProcess()->HasSwitch( 2248 switches::kEnableGPUCommandLogging)) { 2249 set_log_commands(true); 2250 } 2251 2252 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch( 2253 switches::kCompileShaderAlwaysSucceeds); 2254 2255 2256 // Take ownership of the context and surface. The surface can be replaced with 2257 // SetSurface. 2258 context_ = context; 2259 surface_ = surface; 2260 2261 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) { 2262 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " 2263 << "failed to initialize."; 2264 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. 2265 Destroy(true); 2266 return false; 2267 } 2268 CHECK_GL_ERROR(); 2269 2270 disallowed_features_ = disallowed_features; 2271 2272 state_.attrib_values.resize(group_->max_vertex_attribs()); 2273 default_vertex_attrib_manager_ = new VertexAttribManager(); 2274 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs()); 2275 2276 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call 2277 DoBindVertexArrayOES(0); 2278 2279 query_manager_.reset(new QueryManager(this, feature_info_.get())); 2280 vertex_array_manager_.reset(new VertexArrayManager()); 2281 2282 util_.set_num_compressed_texture_formats( 2283 validators_->compressed_texture_format.GetValues().size()); 2284 2285 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2286 // We have to enable vertex array 0 on OpenGL or it won't render. Note that 2287 // OpenGL ES 2.0 does not have this issue. 2288 glEnableVertexAttribArray(0); 2289 } 2290 glGenBuffersARB(1, &attrib_0_buffer_id_); 2291 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 2292 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); 2293 glBindBuffer(GL_ARRAY_BUFFER, 0); 2294 glGenBuffersARB(1, &fixed_attrib_buffer_id_); 2295 2296 state_.texture_units.resize(group_->max_texture_units()); 2297 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) { 2298 glActiveTexture(GL_TEXTURE0 + tt); 2299 // We want the last bind to be 2D. 2300 TextureRef* ref; 2301 if (features().oes_egl_image_external) { 2302 ref = texture_manager()->GetDefaultTextureInfo( 2303 GL_TEXTURE_EXTERNAL_OES); 2304 state_.texture_units[tt].bound_texture_external_oes = ref; 2305 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id()); 2306 } 2307 if (features().arb_texture_rectangle) { 2308 ref = texture_manager()->GetDefaultTextureInfo( 2309 GL_TEXTURE_RECTANGLE_ARB); 2310 state_.texture_units[tt].bound_texture_rectangle_arb = ref; 2311 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id()); 2312 } 2313 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP); 2314 state_.texture_units[tt].bound_texture_cube_map = ref; 2315 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id()); 2316 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); 2317 state_.texture_units[tt].bound_texture_2d = ref; 2318 glBindTexture(GL_TEXTURE_2D, ref->service_id()); 2319 } 2320 glActiveTexture(GL_TEXTURE0); 2321 CHECK_GL_ERROR(); 2322 2323 ContextCreationAttribParser attrib_parser; 2324 if (!attrib_parser.Parse(attribs)) 2325 return false; 2326 2327 if (offscreen) { 2328 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 && 2329 features().chromium_framebuffer_multisample) { 2330 // Per ext_framebuffer_multisample spec, need max bound on sample count. 2331 // max_sample_count must be initialized to a sane value. If 2332 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. 2333 GLint max_sample_count = 1; 2334 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); 2335 offscreen_target_samples_ = std::min(attrib_parser.samples_, 2336 max_sample_count); 2337 } else { 2338 offscreen_target_samples_ = 1; 2339 } 2340 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_; 2341 2342 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 2343 const bool rgb8_supported = 2344 context_->HasExtension("GL_OES_rgb8_rgba8"); 2345 // The only available default render buffer formats in GLES2 have very 2346 // little precision. Don't enable multisampling unless 8-bit render 2347 // buffer formats are available--instead fall back to 8-bit textures. 2348 if (rgb8_supported && offscreen_target_samples_ > 1) { 2349 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2350 GL_RGBA8 : GL_RGB8; 2351 } else { 2352 offscreen_target_samples_ = 1; 2353 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2354 GL_RGBA : GL_RGB; 2355 } 2356 2357 // ANGLE only supports packed depth/stencil formats, so use it if it is 2358 // available. 2359 const bool depth24_stencil8_supported = 2360 context_->HasExtension("GL_OES_packed_depth_stencil"); 2361 VLOG(1) << "GL_OES_packed_depth_stencil " 2362 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2363 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && 2364 depth24_stencil8_supported) { 2365 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2366 offscreen_target_stencil_format_ = 0; 2367 } else { 2368 // It may be the case that this depth/stencil combination is not 2369 // supported, but this will be checked later by CheckFramebufferStatus. 2370 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ? 2371 GL_DEPTH_COMPONENT16 : 0; 2372 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ? 2373 GL_STENCIL_INDEX8 : 0; 2374 } 2375 } else { 2376 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2377 GL_RGBA : GL_RGB; 2378 2379 // If depth is requested at all, use the packed depth stencil format if 2380 // it's available, as some desktop GL drivers don't support any non-packed 2381 // formats for depth attachments. 2382 const bool depth24_stencil8_supported = 2383 context_->HasExtension("GL_EXT_packed_depth_stencil"); 2384 VLOG(1) << "GL_EXT_packed_depth_stencil " 2385 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2386 2387 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && 2388 depth24_stencil8_supported) { 2389 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2390 offscreen_target_stencil_format_ = 0; 2391 } else { 2392 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ? 2393 GL_DEPTH_COMPONENT : 0; 2394 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ? 2395 GL_STENCIL_INDEX : 0; 2396 } 2397 } 2398 2399 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ? 2400 GL_RGBA : GL_RGB; 2401 2402 // Create the target frame buffer. This is the one that the client renders 2403 // directly to. 2404 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this)); 2405 offscreen_target_frame_buffer_->Create(); 2406 // Due to GLES2 format limitations, either the color texture (for 2407 // non-multisampling) or the color render buffer (for multisampling) will be 2408 // attached to the offscreen frame buffer. The render buffer has more 2409 // limited formats available to it, but the texture can't do multisampling. 2410 if (IsOffscreenBufferMultisampled()) { 2411 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this)); 2412 offscreen_target_color_render_buffer_->Create(); 2413 } else { 2414 offscreen_target_color_texture_.reset(new BackTexture(this)); 2415 offscreen_target_color_texture_->Create(); 2416 } 2417 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this)); 2418 offscreen_target_depth_render_buffer_->Create(); 2419 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this)); 2420 offscreen_target_stencil_render_buffer_->Create(); 2421 2422 // Create the saved offscreen texture. The target frame buffer is copied 2423 // here when SwapBuffers is called. 2424 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this)); 2425 offscreen_saved_frame_buffer_->Create(); 2426 // 2427 offscreen_saved_color_texture_.reset(new BackTexture(this)); 2428 offscreen_saved_color_texture_->Create(); 2429 2430 // Allocate the render buffers at their initial size and check the status 2431 // of the frame buffers is okay. 2432 if (!ResizeOffscreenFrameBuffer(size)) { 2433 LOG(ERROR) << "Could not allocate offscreen buffer storage."; 2434 Destroy(true); 2435 return false; 2436 } 2437 2438 // Allocate the offscreen saved color texture. 2439 DCHECK(offscreen_saved_color_format_); 2440 offscreen_saved_color_texture_->AllocateStorage( 2441 gfx::Size(1, 1), offscreen_saved_color_format_, true); 2442 2443 offscreen_saved_frame_buffer_->AttachRenderTexture( 2444 offscreen_saved_color_texture_.get()); 2445 if (offscreen_saved_frame_buffer_->CheckStatus() != 2446 GL_FRAMEBUFFER_COMPLETE) { 2447 LOG(ERROR) << "Offscreen saved FBO was incomplete."; 2448 Destroy(true); 2449 return false; 2450 } 2451 2452 // Bind to the new default frame buffer (the offscreen target frame buffer). 2453 // This should now be associated with ID zero. 2454 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2455 } else { 2456 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); 2457 // These are NOT if the back buffer has these proprorties. They are 2458 // if we want the command buffer to enforce them regardless of what 2459 // the real backbuffer is assuming the real back buffer gives us more than 2460 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll 2461 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we 2462 // can't do anything about that. 2463 2464 GLint v = 0; 2465 glGetIntegerv(GL_ALPHA_BITS, &v); 2466 // This checks if the user requested RGBA and we have RGBA then RGBA. If the 2467 // user requested RGB then RGB. If the user did not specify a preference 2468 // than use whatever we were given. Same for DEPTH and STENCIL. 2469 back_buffer_color_format_ = 2470 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB; 2471 glGetIntegerv(GL_DEPTH_BITS, &v); 2472 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0; 2473 glGetIntegerv(GL_STENCIL_BITS, &v); 2474 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0; 2475 } 2476 2477 // OpenGL ES 2.0 implicitly enables the desktop GL capability 2478 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact 2479 // isn't well documented; it was discovered in the Khronos OpenGL ES 2480 // mailing list archives. It also implicitly enables the desktop GL 2481 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord 2482 // variable in fragment shaders. 2483 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2484 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); 2485 glEnable(GL_POINT_SPRITE); 2486 } 2487 2488 has_robustness_extension_ = 2489 context->HasExtension("GL_ARB_robustness") || 2490 context->HasExtension("GL_EXT_robustness"); 2491 2492 if (!InitializeShaderTranslator()) { 2493 return false; 2494 } 2495 2496 state_.viewport_width = size.width(); 2497 state_.viewport_height = size.height(); 2498 2499 GLint viewport_params[4] = { 0 }; 2500 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); 2501 viewport_max_width_ = viewport_params[0]; 2502 viewport_max_height_ = viewport_params[1]; 2503 2504 state_.scissor_width = state_.viewport_width; 2505 state_.scissor_height = state_.viewport_height; 2506 2507 // Set all the default state because some GL drivers get it wrong. 2508 state_.InitCapabilities(); 2509 state_.InitState(); 2510 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 2511 2512 DoBindBuffer(GL_ARRAY_BUFFER, 0); 2513 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2514 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2515 DoBindRenderbuffer(GL_RENDERBUFFER, 0); 2516 2517 bool call_gl_clear = true; 2518 #if defined(OS_ANDROID) 2519 // Temporary workaround for Android WebView because this clear ignores the 2520 // clip and corrupts that external UI of the App. Not calling glClear is ok 2521 // because the system already clears the buffer before each draw. Proper 2522 // fix might be setting the scissor clip properly before initialize. See 2523 // crbug.com/259023 for details. 2524 call_gl_clear = surface_->GetHandle(); 2525 #endif 2526 if (call_gl_clear) { 2527 // Clear the backbuffer. 2528 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2529 } 2530 2531 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { 2532 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 2533 } 2534 2535 if (feature_info_->workarounds().unbind_fbo_on_context_switch) { 2536 context_->SetUnbindFboOnMakeCurrent(); 2537 } 2538 2539 // Only compositor contexts are known to use only the subset of GL 2540 // that can be safely migrated between the iGPU and the dGPU. Mark 2541 // those contexts as safe to forcibly transition between the GPUs. 2542 // http://crbug.com/180876, http://crbug.com/227228 2543 if (!offscreen) 2544 context_->SetSafeToForceGpuSwitch(); 2545 2546 async_pixel_transfer_manager_.reset( 2547 AsyncPixelTransferManager::Create(context.get())); 2548 async_pixel_transfer_manager_->Initialize(texture_manager()); 2549 2550 framebuffer_manager()->AddObserver(this); 2551 2552 return true; 2553 } 2554 2555 void GLES2DecoderImpl::UpdateCapabilities() { 2556 util_.set_num_compressed_texture_formats( 2557 validators_->compressed_texture_format.GetValues().size()); 2558 util_.set_num_shader_binary_formats( 2559 validators_->shader_binary_format.GetValues().size()); 2560 } 2561 2562 bool GLES2DecoderImpl::InitializeShaderTranslator() { 2563 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator"); 2564 2565 if (!use_shader_translator_) { 2566 return true; 2567 } 2568 ShBuiltInResources resources; 2569 ShInitBuiltInResources(&resources); 2570 resources.MaxVertexAttribs = group_->max_vertex_attribs(); 2571 resources.MaxVertexUniformVectors = 2572 group_->max_vertex_uniform_vectors(); 2573 resources.MaxVaryingVectors = group_->max_varying_vectors(); 2574 resources.MaxVertexTextureImageUnits = 2575 group_->max_vertex_texture_image_units(); 2576 resources.MaxCombinedTextureImageUnits = group_->max_texture_units(); 2577 resources.MaxTextureImageUnits = group_->max_texture_image_units(); 2578 resources.MaxFragmentUniformVectors = 2579 group_->max_fragment_uniform_vectors(); 2580 resources.MaxDrawBuffers = group_->max_draw_buffers(); 2581 resources.MaxExpressionComplexity = 256; 2582 resources.MaxCallStackDepth = 256; 2583 2584 #if (ANGLE_SH_VERSION >= 110) 2585 GLint range[2] = { 0, 0 }; 2586 GLint precision = 0; 2587 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, 2588 range, &precision); 2589 resources.FragmentPrecisionHigh = 2590 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision); 2591 #endif 2592 2593 if (force_webgl_glsl_validation_) { 2594 resources.OES_standard_derivatives = derivatives_explicitly_enabled_; 2595 resources.EXT_frag_depth = frag_depth_explicitly_enabled_; 2596 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_; 2597 } else { 2598 resources.OES_standard_derivatives = 2599 features().oes_standard_derivatives ? 1 : 0; 2600 resources.ARB_texture_rectangle = 2601 features().arb_texture_rectangle ? 1 : 0; 2602 resources.OES_EGL_image_external = 2603 features().oes_egl_image_external ? 1 : 0; 2604 resources.EXT_draw_buffers = 2605 features().ext_draw_buffers ? 1 : 0; 2606 resources.EXT_frag_depth = 2607 features().ext_frag_depth ? 1 : 0; 2608 } 2609 2610 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC 2611 : SH_GLES2_SPEC; 2612 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing) 2613 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108 2614 resources.HashFunction = &CityHashForAngle; 2615 #else 2616 resources.HashFunction = &CityHash64; 2617 #endif 2618 else 2619 resources.HashFunction = NULL; 2620 ShaderTranslatorInterface::GlslImplementationType implementation_type = 2621 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ? 2622 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl; 2623 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior = 2624 workarounds().needs_glsl_built_in_function_emulation ? 2625 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated : 2626 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal; 2627 2628 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance(); 2629 vertex_translator_ = cache->GetTranslator( 2630 SH_VERTEX_SHADER, shader_spec, &resources, 2631 implementation_type, function_behavior); 2632 if (!vertex_translator_.get()) { 2633 LOG(ERROR) << "Could not initialize vertex shader translator."; 2634 Destroy(true); 2635 return false; 2636 } 2637 2638 fragment_translator_ = cache->GetTranslator( 2639 SH_FRAGMENT_SHADER, shader_spec, &resources, 2640 implementation_type, function_behavior); 2641 if (!fragment_translator_.get()) { 2642 LOG(ERROR) << "Could not initialize fragment shader translator."; 2643 Destroy(true); 2644 return false; 2645 } 2646 return true; 2647 } 2648 2649 bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) { 2650 for (GLsizei ii = 0; ii < n; ++ii) { 2651 if (GetBuffer(client_ids[ii])) { 2652 return false; 2653 } 2654 } 2655 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2656 glGenBuffersARB(n, service_ids.get()); 2657 for (GLsizei ii = 0; ii < n; ++ii) { 2658 CreateBuffer(client_ids[ii], service_ids[ii]); 2659 } 2660 return true; 2661 } 2662 2663 bool GLES2DecoderImpl::GenFramebuffersHelper( 2664 GLsizei n, const GLuint* client_ids) { 2665 for (GLsizei ii = 0; ii < n; ++ii) { 2666 if (GetFramebuffer(client_ids[ii])) { 2667 return false; 2668 } 2669 } 2670 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2671 glGenFramebuffersEXT(n, service_ids.get()); 2672 for (GLsizei ii = 0; ii < n; ++ii) { 2673 CreateFramebuffer(client_ids[ii], service_ids[ii]); 2674 } 2675 return true; 2676 } 2677 2678 bool GLES2DecoderImpl::GenRenderbuffersHelper( 2679 GLsizei n, const GLuint* client_ids) { 2680 for (GLsizei ii = 0; ii < n; ++ii) { 2681 if (GetRenderbuffer(client_ids[ii])) { 2682 return false; 2683 } 2684 } 2685 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2686 glGenRenderbuffersEXT(n, service_ids.get()); 2687 for (GLsizei ii = 0; ii < n; ++ii) { 2688 CreateRenderbuffer(client_ids[ii], service_ids[ii]); 2689 } 2690 return true; 2691 } 2692 2693 bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) { 2694 for (GLsizei ii = 0; ii < n; ++ii) { 2695 if (GetTexture(client_ids[ii])) { 2696 return false; 2697 } 2698 } 2699 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2700 glGenTextures(n, service_ids.get()); 2701 for (GLsizei ii = 0; ii < n; ++ii) { 2702 CreateTexture(client_ids[ii], service_ids[ii]); 2703 } 2704 return true; 2705 } 2706 2707 void GLES2DecoderImpl::DeleteBuffersHelper( 2708 GLsizei n, const GLuint* client_ids) { 2709 for (GLsizei ii = 0; ii < n; ++ii) { 2710 Buffer* buffer = GetBuffer(client_ids[ii]); 2711 if (buffer && !buffer->IsDeleted()) { 2712 state_.vertex_attrib_manager->Unbind(buffer); 2713 if (state_.bound_array_buffer.get() == buffer) { 2714 state_.bound_array_buffer = NULL; 2715 } 2716 RemoveBuffer(client_ids[ii]); 2717 } 2718 } 2719 } 2720 2721 void GLES2DecoderImpl::DeleteFramebuffersHelper( 2722 GLsizei n, const GLuint* client_ids) { 2723 bool supports_separate_framebuffer_binds = 2724 features().chromium_framebuffer_multisample; 2725 2726 for (GLsizei ii = 0; ii < n; ++ii) { 2727 Framebuffer* framebuffer = 2728 GetFramebuffer(client_ids[ii]); 2729 if (framebuffer && !framebuffer->IsDeleted()) { 2730 if (framebuffer == state_.bound_draw_framebuffer.get()) { 2731 state_.bound_draw_framebuffer = NULL; 2732 clear_state_dirty_ = true; 2733 GLenum target = supports_separate_framebuffer_binds ? 2734 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2735 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2736 } 2737 if (framebuffer == state_.bound_read_framebuffer.get()) { 2738 state_.bound_read_framebuffer = NULL; 2739 GLenum target = supports_separate_framebuffer_binds ? 2740 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2741 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2742 } 2743 OnFboChanged(); 2744 RemoveFramebuffer(client_ids[ii]); 2745 } 2746 } 2747 } 2748 2749 void GLES2DecoderImpl::DeleteRenderbuffersHelper( 2750 GLsizei n, const GLuint* client_ids) { 2751 bool supports_separate_framebuffer_binds = 2752 features().chromium_framebuffer_multisample; 2753 for (GLsizei ii = 0; ii < n; ++ii) { 2754 Renderbuffer* renderbuffer = 2755 GetRenderbuffer(client_ids[ii]); 2756 if (renderbuffer && !renderbuffer->IsDeleted()) { 2757 if (state_.bound_renderbuffer.get() == renderbuffer) { 2758 state_.bound_renderbuffer = NULL; 2759 } 2760 // Unbind from current framebuffers. 2761 if (supports_separate_framebuffer_binds) { 2762 if (state_.bound_read_framebuffer.get()) { 2763 state_.bound_read_framebuffer 2764 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer); 2765 } 2766 if (state_.bound_draw_framebuffer.get()) { 2767 state_.bound_draw_framebuffer 2768 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); 2769 } 2770 } else { 2771 if (state_.bound_draw_framebuffer.get()) { 2772 state_.bound_draw_framebuffer 2773 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer); 2774 } 2775 } 2776 clear_state_dirty_ = true; 2777 RemoveRenderbuffer(client_ids[ii]); 2778 } 2779 } 2780 } 2781 2782 void GLES2DecoderImpl::DeleteTexturesHelper( 2783 GLsizei n, const GLuint* client_ids) { 2784 bool supports_separate_framebuffer_binds = 2785 features().chromium_framebuffer_multisample; 2786 for (GLsizei ii = 0; ii < n; ++ii) { 2787 TextureRef* texture_ref = GetTexture(client_ids[ii]); 2788 if (texture_ref) { 2789 Texture* texture = texture_ref->texture(); 2790 if (texture->IsAttachedToFramebuffer()) { 2791 clear_state_dirty_ = true; 2792 } 2793 // Unbind texture_ref from texture_ref units. 2794 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) { 2795 state_.texture_units[jj].Unbind(texture_ref); 2796 } 2797 // Unbind from current framebuffers. 2798 if (supports_separate_framebuffer_binds) { 2799 if (state_.bound_read_framebuffer.get()) { 2800 state_.bound_read_framebuffer 2801 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref); 2802 } 2803 if (state_.bound_draw_framebuffer.get()) { 2804 state_.bound_draw_framebuffer 2805 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref); 2806 } 2807 } else { 2808 if (state_.bound_draw_framebuffer.get()) { 2809 state_.bound_draw_framebuffer 2810 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); 2811 } 2812 } 2813 #if defined(OS_MACOSX) 2814 GLuint service_id = texture->service_id(); 2815 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) { 2816 ReleaseIOSurfaceForTexture(service_id); 2817 } 2818 #endif 2819 RemoveTexture(client_ids[ii]); 2820 } 2821 } 2822 } 2823 2824 // } // anonymous namespace 2825 2826 bool GLES2DecoderImpl::MakeCurrent() { 2827 if (!context_.get() || !context_->MakeCurrent(surface_.get())) 2828 return false; 2829 2830 if (WasContextLost()) { 2831 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; 2832 2833 // Some D3D drivers cannot recover from device lost in the GPU process 2834 // sandbox. Allow a new GPU process to launch. 2835 if (workarounds().exit_on_context_lost) { 2836 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset" 2837 << " a D3D device in the Chrome GPU process sandbox."; 2838 exit(0); 2839 } 2840 2841 return false; 2842 } 2843 2844 ProcessFinishedAsyncTransfers(); 2845 2846 // Rebind the FBO if it was unbound by the context. 2847 if (workarounds().unbind_fbo_on_context_switch) 2848 RestoreFramebufferBindings(); 2849 2850 clear_state_dirty_ = true; 2851 2852 return true; 2853 } 2854 2855 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { 2856 ProcessPendingReadPixels(); 2857 if (engine() && query_manager_.get()) 2858 query_manager_->ProcessPendingTransferQueries(); 2859 2860 // TODO(epenner): Is there a better place to do this? 2861 // This needs to occur before we execute any batch of commands 2862 // from the client, as the client may have recieved an async 2863 // completion while issuing those commands. 2864 // "DidFlushStart" would be ideal if we had such a callback. 2865 async_pixel_transfer_manager_->BindCompletedAsyncTransfers(); 2866 } 2867 2868 void GLES2DecoderImpl::ReleaseCurrent() { 2869 if (context_.get()) 2870 context_->ReleaseCurrent(surface_.get()); 2871 } 2872 2873 void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() { 2874 Renderbuffer* renderbuffer = 2875 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 2876 glBindRenderbufferEXT( 2877 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0); 2878 } 2879 2880 static void RebindCurrentFramebuffer( 2881 GLenum target, 2882 Framebuffer* framebuffer, 2883 GLuint back_buffer_service_id) { 2884 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0; 2885 2886 if (framebuffer_id == 0) { 2887 framebuffer_id = back_buffer_service_id; 2888 } 2889 2890 glBindFramebufferEXT(target, framebuffer_id); 2891 } 2892 2893 void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { 2894 clear_state_dirty_ = true; 2895 2896 if (!features().chromium_framebuffer_multisample) { 2897 RebindCurrentFramebuffer( 2898 GL_FRAMEBUFFER, 2899 state_.bound_draw_framebuffer.get(), 2900 GetBackbufferServiceId()); 2901 } else { 2902 RebindCurrentFramebuffer( 2903 GL_READ_FRAMEBUFFER_EXT, 2904 state_.bound_read_framebuffer.get(), 2905 GetBackbufferServiceId()); 2906 RebindCurrentFramebuffer( 2907 GL_DRAW_FRAMEBUFFER_EXT, 2908 state_.bound_draw_framebuffer.get(), 2909 GetBackbufferServiceId()); 2910 } 2911 OnFboChanged(); 2912 } 2913 2914 void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() { 2915 TextureUnit& info = state_.texture_units[0]; 2916 GLuint last_id; 2917 if (info.bound_texture_2d.get()) { 2918 last_id = info.bound_texture_2d->service_id(); 2919 } else { 2920 last_id = 0; 2921 } 2922 2923 glBindTexture(GL_TEXTURE_2D, last_id); 2924 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 2925 } 2926 2927 bool GLES2DecoderImpl::CheckFramebufferValid( 2928 Framebuffer* framebuffer, 2929 GLenum target, const char* func_name) { 2930 if (!framebuffer) { 2931 if (backbuffer_needs_clear_bits_) { 2932 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 2933 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 2934 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 2935 glClearStencil(0); 2936 glStencilMask(-1); 2937 glClearDepth(1.0f); 2938 glDepthMask(true); 2939 glDisable(GL_SCISSOR_TEST); 2940 glClear(backbuffer_needs_clear_bits_); 2941 backbuffer_needs_clear_bits_ = 0; 2942 RestoreClearState(); 2943 } 2944 return true; 2945 } 2946 2947 if (framebuffer_manager()->IsComplete(framebuffer)) { 2948 return true; 2949 } 2950 2951 GLenum completeness = framebuffer->IsPossiblyComplete(); 2952 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 2953 LOCAL_SET_GL_ERROR( 2954 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete"); 2955 return false; 2956 } 2957 2958 // Are all the attachments cleared? 2959 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() || 2960 texture_manager()->HaveUnclearedMips()) { 2961 if (!framebuffer->IsCleared()) { 2962 // Can we clear them? 2963 if (framebuffer->GetStatus(texture_manager(), target) != 2964 GL_FRAMEBUFFER_COMPLETE) { 2965 LOCAL_SET_GL_ERROR( 2966 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 2967 "framebuffer incomplete (clear)"); 2968 return false; 2969 } 2970 ClearUnclearedAttachments(target, framebuffer); 2971 } 2972 } 2973 2974 if (!framebuffer_manager()->IsComplete(framebuffer)) { 2975 if (framebuffer->GetStatus(texture_manager(), target) != 2976 GL_FRAMEBUFFER_COMPLETE) { 2977 LOCAL_SET_GL_ERROR( 2978 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 2979 "framebuffer incomplete (check)"); 2980 return false; 2981 } 2982 framebuffer_manager()->MarkAsComplete(framebuffer); 2983 } 2984 2985 // NOTE: At this point we don't know if the framebuffer is complete but 2986 // we DO know that everything that needs to be cleared has been cleared. 2987 return true; 2988 } 2989 2990 bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) { 2991 if (!features().chromium_framebuffer_multisample) { 2992 bool valid = CheckFramebufferValid( 2993 state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, func_name); 2994 2995 if (valid) 2996 OnUseFramebuffer(); 2997 2998 return valid; 2999 } 3000 return CheckFramebufferValid(state_.bound_draw_framebuffer.get(), 3001 GL_DRAW_FRAMEBUFFER_EXT, 3002 func_name) && 3003 CheckFramebufferValid(state_.bound_read_framebuffer.get(), 3004 GL_READ_FRAMEBUFFER_EXT, 3005 func_name); 3006 } 3007 3008 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { 3009 Framebuffer* framebuffer = 3010 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3011 if (framebuffer != NULL) { 3012 const Framebuffer::Attachment* attachment = 3013 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0); 3014 if (attachment) { 3015 return gfx::Size(attachment->width(), attachment->height()); 3016 } 3017 return gfx::Size(0, 0); 3018 } else if (offscreen_target_frame_buffer_.get()) { 3019 return offscreen_size_; 3020 } else { 3021 return surface_->GetSize(); 3022 } 3023 } 3024 3025 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { 3026 Framebuffer* framebuffer = 3027 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3028 if (framebuffer != NULL) { 3029 return framebuffer->GetColorAttachmentFormat(); 3030 } else if (offscreen_target_frame_buffer_.get()) { 3031 return offscreen_target_color_format_; 3032 } else { 3033 return back_buffer_color_format_; 3034 } 3035 } 3036 3037 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() { 3038 Framebuffer* framebuffer = 3039 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3040 if (framebuffer != NULL) { 3041 return framebuffer->GetColorAttachmentFormat(); 3042 } else if (offscreen_target_frame_buffer_.get()) { 3043 return offscreen_target_color_format_; 3044 } else { 3045 return back_buffer_color_format_; 3046 } 3047 } 3048 3049 void GLES2DecoderImpl::UpdateParentTextureInfo() { 3050 if (!offscreen_saved_color_texture_info_.get()) 3051 return; 3052 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); 3053 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); 3054 texture_manager()->SetLevelInfo( 3055 offscreen_saved_color_texture_info_.get(), 3056 GL_TEXTURE_2D, 3057 0, // level 3058 GL_RGBA, 3059 offscreen_size_.width(), 3060 offscreen_size_.height(), 3061 1, // depth 3062 0, // border 3063 GL_RGBA, 3064 GL_UNSIGNED_BYTE, 3065 true); 3066 texture_manager()->SetParameter( 3067 "UpdateParentTextureInfo", 3068 GetErrorState(), 3069 offscreen_saved_color_texture_info_.get(), 3070 GL_TEXTURE_MAG_FILTER, 3071 GL_NEAREST); 3072 texture_manager()->SetParameter( 3073 "UpdateParentTextureInfo", 3074 GetErrorState(), 3075 offscreen_saved_color_texture_info_.get(), 3076 GL_TEXTURE_MIN_FILTER, 3077 GL_NEAREST); 3078 texture_manager()->SetParameter( 3079 "UpdateParentTextureInfo", 3080 GetErrorState(), 3081 offscreen_saved_color_texture_info_.get(), 3082 GL_TEXTURE_WRAP_S, 3083 GL_CLAMP_TO_EDGE); 3084 texture_manager()->SetParameter( 3085 "UpdateParentTextureInfo", 3086 GetErrorState(), 3087 offscreen_saved_color_texture_info_.get(), 3088 GL_TEXTURE_WRAP_T, 3089 GL_CLAMP_TO_EDGE); 3090 TextureRef* texture_ref = GetTextureInfoForTarget(target); 3091 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0); 3092 } 3093 3094 void GLES2DecoderImpl::SetResizeCallback( 3095 const base::Callback<void(gfx::Size, float)>& callback) { 3096 resize_callback_ = callback; 3097 } 3098 3099 Logger* GLES2DecoderImpl::GetLogger() { 3100 return &logger_; 3101 } 3102 3103 ErrorState* GLES2DecoderImpl::GetErrorState() { 3104 return state_.GetErrorState(); 3105 } 3106 3107 void GLES2DecoderImpl::SetShaderCacheCallback( 3108 const ShaderCacheCallback& callback) { 3109 shader_cache_callback_ = callback; 3110 } 3111 3112 void GLES2DecoderImpl::SetWaitSyncPointCallback( 3113 const WaitSyncPointCallback& callback) { 3114 wait_sync_point_callback_ = callback; 3115 } 3116 3117 AsyncPixelTransferManager* 3118 GLES2DecoderImpl::GetAsyncPixelTransferManager() { 3119 return async_pixel_transfer_manager_.get(); 3120 } 3121 3122 void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() { 3123 async_pixel_transfer_manager_.reset(); 3124 } 3125 3126 void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest( 3127 AsyncPixelTransferManager* manager) { 3128 async_pixel_transfer_manager_ = make_scoped_ptr(manager); 3129 } 3130 3131 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, 3132 uint32* service_texture_id) { 3133 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id); 3134 if (texture_ref) { 3135 *service_texture_id = texture_ref->service_id(); 3136 return true; 3137 } 3138 return false; 3139 } 3140 3141 uint32 GLES2DecoderImpl::GetTextureUploadCount() { 3142 return texture_upload_count_ + 3143 async_pixel_transfer_manager_->GetTextureUploadCount(); 3144 } 3145 3146 base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() { 3147 return total_texture_upload_time_ + 3148 async_pixel_transfer_manager_->GetTotalTextureUploadTime(); 3149 } 3150 3151 base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() { 3152 return total_processing_commands_time_; 3153 } 3154 3155 void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) { 3156 total_processing_commands_time_ += time; 3157 } 3158 3159 void GLES2DecoderImpl::Destroy(bool have_context) { 3160 if (!initialized()) 3161 return; 3162 3163 DCHECK(!have_context || context_->IsCurrent(NULL)); 3164 3165 // Unbind everything. 3166 state_.vertex_attrib_manager = NULL; 3167 default_vertex_attrib_manager_ = NULL; 3168 state_.texture_units.clear(); 3169 state_.bound_array_buffer = NULL; 3170 state_.current_query = NULL; 3171 state_.bound_read_framebuffer = NULL; 3172 state_.bound_draw_framebuffer = NULL; 3173 state_.bound_renderbuffer = NULL; 3174 3175 if (offscreen_saved_color_texture_info_.get()) { 3176 DCHECK(offscreen_target_color_texture_); 3177 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(), 3178 offscreen_saved_color_texture_->id()); 3179 offscreen_saved_color_texture_->Invalidate(); 3180 offscreen_saved_color_texture_info_ = NULL; 3181 } 3182 if (have_context) { 3183 if (copy_texture_CHROMIUM_.get()) { 3184 copy_texture_CHROMIUM_->Destroy(); 3185 copy_texture_CHROMIUM_.reset(); 3186 } 3187 3188 if (state_.current_program.get()) { 3189 program_manager()->UnuseProgram(shader_manager(), 3190 state_.current_program.get()); 3191 } 3192 3193 if (attrib_0_buffer_id_) { 3194 glDeleteBuffersARB(1, &attrib_0_buffer_id_); 3195 } 3196 if (fixed_attrib_buffer_id_) { 3197 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_); 3198 } 3199 3200 if (offscreen_target_frame_buffer_.get()) 3201 offscreen_target_frame_buffer_->Destroy(); 3202 if (offscreen_target_color_texture_.get()) 3203 offscreen_target_color_texture_->Destroy(); 3204 if (offscreen_target_color_render_buffer_.get()) 3205 offscreen_target_color_render_buffer_->Destroy(); 3206 if (offscreen_target_depth_render_buffer_.get()) 3207 offscreen_target_depth_render_buffer_->Destroy(); 3208 if (offscreen_target_stencil_render_buffer_.get()) 3209 offscreen_target_stencil_render_buffer_->Destroy(); 3210 if (offscreen_saved_frame_buffer_.get()) 3211 offscreen_saved_frame_buffer_->Destroy(); 3212 if (offscreen_saved_color_texture_.get()) 3213 offscreen_saved_color_texture_->Destroy(); 3214 if (offscreen_resolved_frame_buffer_.get()) 3215 offscreen_resolved_frame_buffer_->Destroy(); 3216 if (offscreen_resolved_color_texture_.get()) 3217 offscreen_resolved_color_texture_->Destroy(); 3218 } else { 3219 if (offscreen_target_frame_buffer_.get()) 3220 offscreen_target_frame_buffer_->Invalidate(); 3221 if (offscreen_target_color_texture_.get()) 3222 offscreen_target_color_texture_->Invalidate(); 3223 if (offscreen_target_color_render_buffer_.get()) 3224 offscreen_target_color_render_buffer_->Invalidate(); 3225 if (offscreen_target_depth_render_buffer_.get()) 3226 offscreen_target_depth_render_buffer_->Invalidate(); 3227 if (offscreen_target_stencil_render_buffer_.get()) 3228 offscreen_target_stencil_render_buffer_->Invalidate(); 3229 if (offscreen_saved_frame_buffer_.get()) 3230 offscreen_saved_frame_buffer_->Invalidate(); 3231 if (offscreen_saved_color_texture_.get()) 3232 offscreen_saved_color_texture_->Invalidate(); 3233 if (offscreen_resolved_frame_buffer_.get()) 3234 offscreen_resolved_frame_buffer_->Invalidate(); 3235 if (offscreen_resolved_color_texture_.get()) 3236 offscreen_resolved_color_texture_->Invalidate(); 3237 } 3238 3239 // Current program must be cleared after calling ProgramManager::UnuseProgram. 3240 // Otherwise, we can leak objects. http://crbug.com/258772. 3241 // state_.current_program must be reset before group_ is reset because 3242 // the later deletes the ProgramManager object that referred by 3243 // state_.current_program object. 3244 state_.current_program = NULL; 3245 3246 copy_texture_CHROMIUM_.reset(); 3247 3248 if (query_manager_.get()) { 3249 query_manager_->Destroy(have_context); 3250 query_manager_.reset(); 3251 } 3252 3253 if (vertex_array_manager_ .get()) { 3254 vertex_array_manager_->Destroy(have_context); 3255 vertex_array_manager_.reset(); 3256 } 3257 3258 offscreen_target_frame_buffer_.reset(); 3259 offscreen_target_color_texture_.reset(); 3260 offscreen_target_color_render_buffer_.reset(); 3261 offscreen_target_depth_render_buffer_.reset(); 3262 offscreen_target_stencil_render_buffer_.reset(); 3263 offscreen_saved_frame_buffer_.reset(); 3264 offscreen_saved_color_texture_.reset(); 3265 offscreen_resolved_frame_buffer_.reset(); 3266 offscreen_resolved_color_texture_.reset(); 3267 3268 // Should destroy the transfer manager before the texture manager held 3269 // by the context group. 3270 async_pixel_transfer_manager_.reset(); 3271 3272 framebuffer_manager()->RemoveObserver(this); 3273 3274 if (group_.get()) { 3275 group_->Destroy(this, have_context); 3276 group_ = NULL; 3277 } 3278 3279 if (context_.get()) { 3280 context_->ReleaseCurrent(NULL); 3281 context_ = NULL; 3282 } 3283 3284 #if defined(OS_MACOSX) 3285 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin(); 3286 it != texture_to_io_surface_map_.end(); ++it) { 3287 CFRelease(it->second); 3288 } 3289 texture_to_io_surface_map_.clear(); 3290 #endif 3291 } 3292 3293 void GLES2DecoderImpl::SetSurface( 3294 const scoped_refptr<gfx::GLSurface>& surface) { 3295 DCHECK(context_->IsCurrent(NULL)); 3296 DCHECK(surface_.get()); 3297 surface_ = surface; 3298 RestoreCurrentFramebufferBindings(); 3299 } 3300 3301 bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) { 3302 if (!offscreen_saved_color_texture_.get()) 3303 return false; 3304 if (!offscreen_saved_color_texture_info_.get()) { 3305 GLuint service_id = offscreen_saved_color_texture_->id(); 3306 offscreen_saved_color_texture_info_ = TextureRef::Create( 3307 texture_manager(), 0, service_id); 3308 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(), 3309 GL_TEXTURE_2D); 3310 UpdateParentTextureInfo(); 3311 } 3312 gpu::gles2::MailboxName name; 3313 memcpy(name.key, mailbox.name, sizeof(mailbox.name)); 3314 return mailbox_manager()->ProduceTexture( 3315 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture()); 3316 } 3317 3318 size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() { 3319 size_t total = 0; 3320 if (offscreen_target_frame_buffer_.get()) { 3321 if (offscreen_target_color_texture_.get()) { 3322 total += offscreen_target_color_texture_->estimated_size(); 3323 } 3324 if (offscreen_target_color_render_buffer_.get()) { 3325 total += offscreen_target_color_render_buffer_->estimated_size(); 3326 } 3327 if (offscreen_target_depth_render_buffer_.get()) { 3328 total += offscreen_target_depth_render_buffer_->estimated_size(); 3329 } 3330 if (offscreen_target_stencil_render_buffer_.get()) { 3331 total += offscreen_target_stencil_render_buffer_->estimated_size(); 3332 } 3333 if (offscreen_saved_color_texture_.get()) { 3334 total += offscreen_saved_color_texture_->estimated_size(); 3335 } 3336 if (offscreen_resolved_color_texture_.get()) { 3337 total += offscreen_resolved_color_texture_->estimated_size(); 3338 } 3339 } else { 3340 gfx::Size size = surface_->GetSize(); 3341 total += size.width() * size.height() * 3342 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_); 3343 } 3344 return total; 3345 } 3346 3347 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { 3348 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3349 if (!is_offscreen) { 3350 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called " 3351 << " with an onscreen framebuffer."; 3352 return false; 3353 } 3354 3355 if (offscreen_size_ == size) 3356 return true; 3357 3358 offscreen_size_ = size; 3359 int w = offscreen_size_.width(); 3360 int h = offscreen_size_.height(); 3361 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) { 3362 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3363 << "to allocate storage due to excessive dimensions."; 3364 return false; 3365 } 3366 3367 // Reallocate the offscreen target buffers. 3368 DCHECK(offscreen_target_color_format_); 3369 if (IsOffscreenBufferMultisampled()) { 3370 if (!offscreen_target_color_render_buffer_->AllocateStorage( 3371 offscreen_size_, offscreen_target_color_format_, 3372 offscreen_target_samples_)) { 3373 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3374 << "to allocate storage for offscreen target color buffer."; 3375 return false; 3376 } 3377 } else { 3378 if (!offscreen_target_color_texture_->AllocateStorage( 3379 offscreen_size_, offscreen_target_color_format_, false)) { 3380 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3381 << "to allocate storage for offscreen target color texture."; 3382 return false; 3383 } 3384 } 3385 if (offscreen_target_depth_format_ && 3386 !offscreen_target_depth_render_buffer_->AllocateStorage( 3387 offscreen_size_, offscreen_target_depth_format_, 3388 offscreen_target_samples_)) { 3389 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3390 << "to allocate storage for offscreen target depth buffer."; 3391 return false; 3392 } 3393 if (offscreen_target_stencil_format_ && 3394 !offscreen_target_stencil_render_buffer_->AllocateStorage( 3395 offscreen_size_, offscreen_target_stencil_format_, 3396 offscreen_target_samples_)) { 3397 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3398 << "to allocate storage for offscreen target stencil buffer."; 3399 return false; 3400 } 3401 3402 // Attach the offscreen target buffers to the target frame buffer. 3403 if (IsOffscreenBufferMultisampled()) { 3404 offscreen_target_frame_buffer_->AttachRenderBuffer( 3405 GL_COLOR_ATTACHMENT0, 3406 offscreen_target_color_render_buffer_.get()); 3407 } else { 3408 offscreen_target_frame_buffer_->AttachRenderTexture( 3409 offscreen_target_color_texture_.get()); 3410 } 3411 if (offscreen_target_depth_format_) { 3412 offscreen_target_frame_buffer_->AttachRenderBuffer( 3413 GL_DEPTH_ATTACHMENT, 3414 offscreen_target_depth_render_buffer_.get()); 3415 } 3416 const bool packed_depth_stencil = 3417 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3418 if (packed_depth_stencil) { 3419 offscreen_target_frame_buffer_->AttachRenderBuffer( 3420 GL_STENCIL_ATTACHMENT, 3421 offscreen_target_depth_render_buffer_.get()); 3422 } else if (offscreen_target_stencil_format_) { 3423 offscreen_target_frame_buffer_->AttachRenderBuffer( 3424 GL_STENCIL_ATTACHMENT, 3425 offscreen_target_stencil_render_buffer_.get()); 3426 } 3427 3428 if (offscreen_target_frame_buffer_->CheckStatus() != 3429 GL_FRAMEBUFFER_COMPLETE) { 3430 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3431 << "because offscreen FBO was incomplete."; 3432 return false; 3433 } 3434 3435 // Clear the target frame buffer. 3436 { 3437 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id()); 3438 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 3439 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 3440 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3441 glClearStencil(0); 3442 glStencilMaskSeparate(GL_FRONT, -1); 3443 glStencilMaskSeparate(GL_BACK, -1); 3444 glClearDepth(0); 3445 glDepthMask(GL_TRUE); 3446 glDisable(GL_SCISSOR_TEST); 3447 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 3448 RestoreClearState(); 3449 } 3450 3451 // Destroy the offscreen resolved framebuffers. 3452 if (offscreen_resolved_frame_buffer_.get()) 3453 offscreen_resolved_frame_buffer_->Destroy(); 3454 if (offscreen_resolved_color_texture_.get()) 3455 offscreen_resolved_color_texture_->Destroy(); 3456 offscreen_resolved_color_texture_.reset(); 3457 offscreen_resolved_frame_buffer_.reset(); 3458 3459 return true; 3460 } 3461 3462 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM( 3463 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) { 3464 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws()) 3465 return error::kDeferCommandUntilLater; 3466 3467 GLuint width = static_cast<GLuint>(c.width); 3468 GLuint height = static_cast<GLuint>(c.height); 3469 GLfloat scale_factor = c.scale_factor; 3470 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height); 3471 3472 width = std::max(1U, width); 3473 height = std::max(1U, height); 3474 3475 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \ 3476 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 3477 // Make sure that we are done drawing to the back buffer before resizing. 3478 glFinish(); 3479 #endif 3480 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3481 if (is_offscreen) { 3482 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) { 3483 LOG(ERROR) << "GLES2DecoderImpl: Context lost because " 3484 << "ResizeOffscreenFrameBuffer failed."; 3485 return error::kLostContext; 3486 } 3487 } 3488 3489 if (!resize_callback_.is_null()) { 3490 resize_callback_.Run(gfx::Size(width, height), scale_factor); 3491 DCHECK(context_->IsCurrent(surface_.get())); 3492 if (!context_->IsCurrent(surface_.get())) { 3493 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer " 3494 << "current after resize callback."; 3495 return error::kLostContext; 3496 } 3497 } 3498 3499 return error::kNoError; 3500 } 3501 3502 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { 3503 if (command_id > kStartPoint && command_id < kNumCommands) { 3504 return gles2::GetCommandName(static_cast<CommandId>(command_id)); 3505 } 3506 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); 3507 } 3508 3509 // Decode command with its arguments, and call the corresponding GL function. 3510 // Note: args is a pointer to the command buffer. As such, it could be changed 3511 // by a (malicious) client at any time, so if validation has to happen, it 3512 // should operate on a copy of them. 3513 error::Error GLES2DecoderImpl::DoCommand( 3514 unsigned int command, 3515 unsigned int arg_count, 3516 const void* cmd_data) { 3517 error::Error result = error::kNoError; 3518 if (log_commands()) { 3519 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried 3520 // LOG(INFO), tried VLOG(1), no luck. 3521 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: " 3522 << GetCommandName(command); 3523 } 3524 unsigned int command_index = command - kStartPoint - 1; 3525 if (command_index < arraysize(g_command_info)) { 3526 const CommandInfo& info = g_command_info[command_index]; 3527 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); 3528 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || 3529 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { 3530 uint32 immediate_data_size = 3531 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT 3532 switch (command) { 3533 #define GLES2_CMD_OP(name) \ 3534 case cmds::name::kCmdId: \ 3535 result = Handle ## name( \ 3536 immediate_data_size, \ 3537 *static_cast<const gles2::cmds::name*>(cmd_data)); \ 3538 break; \ 3539 3540 GLES2_COMMAND_LIST(GLES2_CMD_OP) 3541 #undef GLES2_CMD_OP 3542 } 3543 if (debug()) { 3544 GLenum error; 3545 while ((error = glGetError()) != GL_NO_ERROR) { 3546 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] " 3547 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : " 3548 << GetCommandName(command); 3549 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver"); 3550 } 3551 } 3552 } else { 3553 result = error::kInvalidArguments; 3554 } 3555 } else { 3556 result = DoCommonCommand(command, arg_count, cmd_data); 3557 } 3558 if (result == error::kNoError && current_decoder_error_ != error::kNoError) { 3559 result = current_decoder_error_; 3560 current_decoder_error_ = error::kNoError; 3561 } 3562 return result; 3563 } 3564 3565 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { 3566 buffer_manager()->RemoveBuffer(client_id); 3567 } 3568 3569 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { 3570 if (GetProgram(client_id)) { 3571 return false; 3572 } 3573 GLuint service_id = glCreateProgram(); 3574 if (service_id != 0) { 3575 CreateProgram(client_id, service_id); 3576 } 3577 return true; 3578 } 3579 3580 bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { 3581 if (GetShader(client_id)) { 3582 return false; 3583 } 3584 GLuint service_id = glCreateShader(type); 3585 if (service_id != 0) { 3586 CreateShader(client_id, service_id, type); 3587 } 3588 return true; 3589 } 3590 3591 void GLES2DecoderImpl::DoFinish() { 3592 glFinish(); 3593 ProcessPendingReadPixels(); 3594 ProcessPendingQueries(); 3595 } 3596 3597 void GLES2DecoderImpl::DoFlush() { 3598 glFlush(); 3599 ProcessPendingQueries(); 3600 } 3601 3602 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { 3603 GLuint texture_index = texture_unit - GL_TEXTURE0; 3604 if (texture_index >= state_.texture_units.size()) { 3605 LOCAL_SET_GL_ERROR_INVALID_ENUM( 3606 "glActiveTexture", texture_unit, "texture_unit"); 3607 return; 3608 } 3609 state_.active_texture_unit = texture_index; 3610 glActiveTexture(texture_unit); 3611 } 3612 3613 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { 3614 Buffer* buffer = NULL; 3615 GLuint service_id = 0; 3616 if (client_id != 0) { 3617 buffer = GetBuffer(client_id); 3618 if (!buffer) { 3619 if (!group_->bind_generates_resource()) { 3620 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers"; 3621 current_decoder_error_ = error::kGenericError; 3622 return; 3623 } 3624 3625 // It's a new id so make a buffer buffer for it. 3626 glGenBuffersARB(1, &service_id); 3627 CreateBuffer(client_id, service_id); 3628 buffer = GetBuffer(client_id); 3629 IdAllocatorInterface* id_allocator = 3630 group_->GetIdAllocator(id_namespaces::kBuffers); 3631 id_allocator->MarkAsUsed(client_id); 3632 } 3633 } 3634 LogClientServiceForInfo(buffer, client_id, "glBindBuffer"); 3635 if (buffer) { 3636 if (!buffer_manager()->SetTarget(buffer, target)) { 3637 LOCAL_SET_GL_ERROR( 3638 GL_INVALID_OPERATION, 3639 "glBindBuffer", "buffer bound to more than 1 target"); 3640 return; 3641 } 3642 service_id = buffer->service_id(); 3643 } 3644 switch (target) { 3645 case GL_ARRAY_BUFFER: 3646 state_.bound_array_buffer = buffer; 3647 break; 3648 case GL_ELEMENT_ARRAY_BUFFER: 3649 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer); 3650 break; 3651 default: 3652 NOTREACHED(); // Validation should prevent us getting here. 3653 break; 3654 } 3655 glBindBuffer(target, service_id); 3656 } 3657 3658 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha( 3659 bool all_draw_buffers) { 3660 Framebuffer* framebuffer = 3661 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3662 if (!all_draw_buffers || !framebuffer) { 3663 return (GLES2Util::GetChannelsForFormat( 3664 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0; 3665 } 3666 return framebuffer->HasAlphaMRT(); 3667 } 3668 3669 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() { 3670 Framebuffer* framebuffer = 3671 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3672 if (framebuffer) { 3673 return framebuffer->HasDepthAttachment(); 3674 } 3675 if (offscreen_target_frame_buffer_.get()) { 3676 return offscreen_target_depth_format_ != 0; 3677 } 3678 return back_buffer_has_depth_; 3679 } 3680 3681 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() { 3682 Framebuffer* framebuffer = 3683 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3684 if (framebuffer) { 3685 return framebuffer->HasStencilAttachment(); 3686 } 3687 if (offscreen_target_frame_buffer_.get()) { 3688 return offscreen_target_stencil_format_ != 0 || 3689 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3690 } 3691 return back_buffer_has_stencil_; 3692 } 3693 3694 void GLES2DecoderImpl::ApplyDirtyState() { 3695 if (clear_state_dirty_) { 3696 glColorMask( 3697 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue, 3698 state_.color_mask_alpha && 3699 BoundFramebufferHasColorAttachmentWithAlpha(true)); 3700 bool have_depth = BoundFramebufferHasDepthAttachment(); 3701 glDepthMask(state_.depth_mask && have_depth); 3702 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth); 3703 bool have_stencil = BoundFramebufferHasStencilAttachment(); 3704 glStencilMaskSeparate( 3705 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0); 3706 glStencilMaskSeparate( 3707 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0); 3708 EnableDisable( 3709 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil); 3710 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face); 3711 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); 3712 EnableDisable(GL_BLEND, state_.enable_flags.blend); 3713 clear_state_dirty_ = false; 3714 } 3715 } 3716 3717 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const { 3718 return (offscreen_target_frame_buffer_.get()) 3719 ? offscreen_target_frame_buffer_->id() 3720 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0); 3721 } 3722 3723 void GLES2DecoderImpl::RestoreState() const { 3724 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState", 3725 "context", logger_.GetLogPrefix()); 3726 // Restore the Framebuffer first because of bugs in Intel drivers. 3727 // Intel drivers incorrectly clip the viewport settings to 3728 // the size of the current framebuffer object. 3729 RestoreFramebufferBindings(); 3730 state_.RestoreState(); 3731 } 3732 3733 void GLES2DecoderImpl::RestoreFramebufferBindings() const { 3734 GLuint service_id = state_.bound_draw_framebuffer.get() 3735 ? state_.bound_draw_framebuffer->service_id() 3736 : GetBackbufferServiceId(); 3737 if (!features().chromium_framebuffer_multisample) { 3738 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id); 3739 } else { 3740 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); 3741 service_id = state_.bound_read_framebuffer.get() 3742 ? state_.bound_read_framebuffer->service_id() 3743 : GetBackbufferServiceId(); 3744 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id); 3745 } 3746 OnFboChanged(); 3747 } 3748 3749 void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const { 3750 Texture* texture = texture_manager()->GetTextureForServiceId(service_id); 3751 if (texture) { 3752 GLenum target = texture->target(); 3753 glBindTexture(target, service_id); 3754 glTexParameteri( 3755 target, GL_TEXTURE_WRAP_S, texture->wrap_s()); 3756 glTexParameteri( 3757 target, GL_TEXTURE_WRAP_T, texture->wrap_t()); 3758 glTexParameteri( 3759 target, GL_TEXTURE_MIN_FILTER, texture->min_filter()); 3760 glTexParameteri( 3761 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter()); 3762 RestoreTextureUnitBindings(state_.active_texture_unit); 3763 } 3764 } 3765 3766 void GLES2DecoderImpl::OnFboChanged() const { 3767 if (workarounds().restore_scissor_on_fbo_change) 3768 state_.fbo_binding_for_scissor_workaround_dirty_ = true; 3769 } 3770 3771 // Called after the FBO is checked for completeness. 3772 void GLES2DecoderImpl::OnUseFramebuffer() const { 3773 if (state_.fbo_binding_for_scissor_workaround_dirty_) { 3774 state_.fbo_binding_for_scissor_workaround_dirty_ = false; 3775 // The driver forgets the correct scissor when modifying the FBO binding. 3776 glScissor(state_.scissor_x, 3777 state_.scissor_y, 3778 state_.scissor_width, 3779 state_.scissor_height); 3780 3781 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker, 3782 // it's unclear how this bug works. 3783 glFlush(); 3784 } 3785 } 3786 3787 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { 3788 Framebuffer* framebuffer = NULL; 3789 GLuint service_id = 0; 3790 if (client_id != 0) { 3791 framebuffer = GetFramebuffer(client_id); 3792 if (!framebuffer) { 3793 if (!group_->bind_generates_resource()) { 3794 LOG(ERROR) 3795 << "glBindFramebuffer: id not generated by glGenFramebuffers"; 3796 current_decoder_error_ = error::kGenericError; 3797 return; 3798 } 3799 3800 // It's a new id so make a framebuffer framebuffer for it. 3801 glGenFramebuffersEXT(1, &service_id); 3802 CreateFramebuffer(client_id, service_id); 3803 framebuffer = GetFramebuffer(client_id); 3804 IdAllocatorInterface* id_allocator = 3805 group_->GetIdAllocator(id_namespaces::kFramebuffers); 3806 id_allocator->MarkAsUsed(client_id); 3807 } else { 3808 service_id = framebuffer->service_id(); 3809 } 3810 framebuffer->MarkAsValid(); 3811 } 3812 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer"); 3813 3814 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { 3815 state_.bound_draw_framebuffer = framebuffer; 3816 } 3817 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { 3818 state_.bound_read_framebuffer = framebuffer; 3819 } 3820 3821 clear_state_dirty_ = true; 3822 3823 // If we are rendering to the backbuffer get the FBO id for any simulated 3824 // backbuffer. 3825 if (framebuffer == NULL) { 3826 service_id = GetBackbufferServiceId(); 3827 } 3828 3829 glBindFramebufferEXT(target, service_id); 3830 OnFboChanged(); 3831 } 3832 3833 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { 3834 Renderbuffer* renderbuffer = NULL; 3835 GLuint service_id = 0; 3836 if (client_id != 0) { 3837 renderbuffer = GetRenderbuffer(client_id); 3838 if (!renderbuffer) { 3839 if (!group_->bind_generates_resource()) { 3840 LOG(ERROR) 3841 << "glBindRenderbuffer: id not generated by glGenRenderbuffers"; 3842 current_decoder_error_ = error::kGenericError; 3843 return; 3844 } 3845 3846 // It's a new id so make a renderbuffer renderbuffer for it. 3847 glGenRenderbuffersEXT(1, &service_id); 3848 CreateRenderbuffer(client_id, service_id); 3849 renderbuffer = GetRenderbuffer(client_id); 3850 IdAllocatorInterface* id_allocator = 3851 group_->GetIdAllocator(id_namespaces::kRenderbuffers); 3852 id_allocator->MarkAsUsed(client_id); 3853 } else { 3854 service_id = renderbuffer->service_id(); 3855 } 3856 renderbuffer->MarkAsValid(); 3857 } 3858 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer"); 3859 state_.bound_renderbuffer = renderbuffer; 3860 glBindRenderbufferEXT(target, service_id); 3861 } 3862 3863 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { 3864 TextureRef* texture_ref = NULL; 3865 GLuint service_id = 0; 3866 if (client_id != 0) { 3867 texture_ref = GetTexture(client_id); 3868 if (!texture_ref) { 3869 if (!group_->bind_generates_resource()) { 3870 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures"; 3871 current_decoder_error_ = error::kGenericError; 3872 return; 3873 } 3874 3875 // It's a new id so make a texture texture for it. 3876 glGenTextures(1, &service_id); 3877 DCHECK_NE(0u, service_id); 3878 CreateTexture(client_id, service_id); 3879 texture_ref = GetTexture(client_id); 3880 IdAllocatorInterface* id_allocator = 3881 group_->GetIdAllocator(id_namespaces::kTextures); 3882 id_allocator->MarkAsUsed(client_id); 3883 } 3884 } else { 3885 texture_ref = texture_manager()->GetDefaultTextureInfo(target); 3886 } 3887 Texture* texture = texture_ref->texture(); 3888 3889 // Check the texture exists 3890 // Check that we are not trying to bind it to a different target. 3891 if (texture->target() != 0 && texture->target() != target) { 3892 LOCAL_SET_GL_ERROR( 3893 GL_INVALID_OPERATION, 3894 "glBindTexture", "texture bound to more than 1 target."); 3895 return; 3896 } 3897 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { 3898 LOCAL_SET_GL_ERROR( 3899 GL_INVALID_OPERATION, 3900 "glBindTexture", "illegal target for stream texture."); 3901 return; 3902 } 3903 LogClientServiceForInfo(texture, client_id, "glBindTexture"); 3904 if (texture->target() == 0) { 3905 texture_manager()->SetTarget(texture_ref, target); 3906 } 3907 glBindTexture(target, texture->service_id()); 3908 3909 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3910 unit.bind_target = target; 3911 switch (target) { 3912 case GL_TEXTURE_2D: 3913 unit.bound_texture_2d = texture_ref; 3914 break; 3915 case GL_TEXTURE_CUBE_MAP: 3916 unit.bound_texture_cube_map = texture_ref; 3917 break; 3918 case GL_TEXTURE_EXTERNAL_OES: 3919 unit.bound_texture_external_oes = texture_ref; 3920 break; 3921 case GL_TEXTURE_RECTANGLE_ARB: 3922 unit.bound_texture_rectangle_arb = texture_ref; 3923 break; 3924 default: 3925 NOTREACHED(); // Validation should prevent us getting here. 3926 break; 3927 } 3928 } 3929 3930 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { 3931 if (state_.vertex_attrib_manager->Enable(index, false)) { 3932 if (index != 0 || 3933 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 3934 glDisableVertexAttribArray(index); 3935 } 3936 } else { 3937 LOCAL_SET_GL_ERROR( 3938 GL_INVALID_VALUE, 3939 "glDisableVertexAttribArray", "index out of range"); 3940 } 3941 } 3942 3943 void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target, 3944 GLsizei numAttachments, 3945 const GLenum* attachments) { 3946 Framebuffer* framebuffer = 3947 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 3948 3949 // Validates the attachments. If one of them fails 3950 // the whole command fails. 3951 for (GLsizei i = 0; i < numAttachments; ++i) { 3952 if ((framebuffer && 3953 !validators_->attachment.IsValid(attachments[i])) || 3954 (!framebuffer && 3955 !validators_->backbuffer_attachment.IsValid(attachments[i]))) { 3956 LOCAL_SET_GL_ERROR_INVALID_ENUM( 3957 "glDiscardFramebufferEXT", attachments[i], "attachments"); 3958 return; 3959 } 3960 } 3961 3962 // Marks each one of them as not cleared 3963 for (GLsizei i = 0; i < numAttachments; ++i) { 3964 if (framebuffer) { 3965 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(), 3966 texture_manager(), 3967 attachments[i], 3968 false); 3969 } else { 3970 switch (attachments[i]) { 3971 case GL_COLOR_EXT: 3972 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT; 3973 break; 3974 case GL_DEPTH_EXT: 3975 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT; 3976 case GL_STENCIL_EXT: 3977 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT; 3978 break; 3979 default: 3980 NOTREACHED(); 3981 break; 3982 } 3983 } 3984 } 3985 3986 glDiscardFramebufferEXT(target, numAttachments, attachments); 3987 } 3988 3989 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { 3990 if (state_.vertex_attrib_manager->Enable(index, true)) { 3991 glEnableVertexAttribArray(index); 3992 } else { 3993 LOCAL_SET_GL_ERROR( 3994 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range"); 3995 } 3996 } 3997 3998 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { 3999 TextureRef* texture_ref = GetTextureInfoForTarget(target); 4000 if (!texture_ref || 4001 !texture_manager()->CanGenerateMipmaps(texture_ref)) { 4002 LOCAL_SET_GL_ERROR( 4003 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips"); 4004 return; 4005 } 4006 4007 if (target == GL_TEXTURE_CUBE_MAP) { 4008 for (int i = 0; i < 6; ++i) { 4009 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; 4010 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) { 4011 LOCAL_SET_GL_ERROR( 4012 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big"); 4013 return; 4014 } 4015 } 4016 } else { 4017 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) { 4018 LOCAL_SET_GL_ERROR( 4019 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big"); 4020 return; 4021 } 4022 } 4023 4024 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap"); 4025 // Workaround for Mac driver bug. In the large scheme of things setting 4026 // glTexParamter twice for glGenerateMipmap is probably not a lage performance 4027 // hit so there's probably no need to make this conditional. The bug appears 4028 // to be that if the filtering mode is set to something that doesn't require 4029 // mipmaps for rendering, or is never set to something other than the default, 4030 // then glGenerateMipmap misbehaves. 4031 if (workarounds().set_texture_filter_before_generating_mipmap) { 4032 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 4033 } 4034 glGenerateMipmapEXT(target); 4035 if (workarounds().set_texture_filter_before_generating_mipmap) { 4036 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, 4037 texture_ref->texture()->min_filter()); 4038 } 4039 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap"); 4040 if (error == GL_NO_ERROR) { 4041 texture_manager()->MarkMipmapsGenerated(texture_ref); 4042 } 4043 } 4044 4045 bool GLES2DecoderImpl::GetHelper( 4046 GLenum pname, GLint* params, GLsizei* num_written) { 4047 DCHECK(num_written); 4048 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 4049 switch (pname) { 4050 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 4051 *num_written = 1; 4052 if (params) { 4053 *params = GL_RGBA; // We don't support other formats. 4054 } 4055 return true; 4056 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 4057 *num_written = 1; 4058 if (params) { 4059 *params = GL_UNSIGNED_BYTE; // We don't support other types. 4060 } 4061 return true; 4062 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 4063 *num_written = 1; 4064 if (params) { 4065 *params = group_->max_fragment_uniform_vectors(); 4066 } 4067 return true; 4068 case GL_MAX_VARYING_VECTORS: 4069 *num_written = 1; 4070 if (params) { 4071 *params = group_->max_varying_vectors(); 4072 } 4073 return true; 4074 case GL_MAX_VERTEX_UNIFORM_VECTORS: 4075 *num_written = 1; 4076 if (params) { 4077 *params = group_->max_vertex_uniform_vectors(); 4078 } 4079 return true; 4080 } 4081 } 4082 switch (pname) { 4083 case GL_MAX_VIEWPORT_DIMS: 4084 if (offscreen_target_frame_buffer_.get()) { 4085 *num_written = 2; 4086 if (params) { 4087 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 4088 params[1] = renderbuffer_manager()->max_renderbuffer_size(); 4089 } 4090 return true; 4091 } 4092 return false; 4093 case GL_MAX_SAMPLES: 4094 *num_written = 1; 4095 if (params) { 4096 params[0] = renderbuffer_manager()->max_samples(); 4097 } 4098 return true; 4099 case GL_MAX_RENDERBUFFER_SIZE: 4100 *num_written = 1; 4101 if (params) { 4102 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 4103 } 4104 return true; 4105 case GL_MAX_TEXTURE_SIZE: 4106 *num_written = 1; 4107 if (params) { 4108 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D); 4109 } 4110 return true; 4111 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 4112 *num_written = 1; 4113 if (params) { 4114 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP); 4115 } 4116 return true; 4117 case GL_MAX_COLOR_ATTACHMENTS_EXT: 4118 *num_written = 1; 4119 if (params) { 4120 params[0] = group_->max_color_attachments(); 4121 } 4122 return true; 4123 case GL_MAX_DRAW_BUFFERS_ARB: 4124 *num_written = 1; 4125 if (params) { 4126 params[0] = group_->max_draw_buffers(); 4127 } 4128 return true; 4129 case GL_ALPHA_BITS: 4130 *num_written = 1; 4131 if (params) { 4132 GLint v = 0; 4133 glGetIntegerv(GL_ALPHA_BITS, &v); 4134 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; 4135 } 4136 return true; 4137 case GL_DEPTH_BITS: 4138 *num_written = 1; 4139 if (params) { 4140 GLint v = 0; 4141 glGetIntegerv(GL_DEPTH_BITS, &v); 4142 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0; 4143 } 4144 return true; 4145 case GL_STENCIL_BITS: 4146 *num_written = 1; 4147 if (params) { 4148 GLint v = 0; 4149 glGetIntegerv(GL_STENCIL_BITS, &v); 4150 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0; 4151 } 4152 return true; 4153 case GL_COMPRESSED_TEXTURE_FORMATS: 4154 *num_written = validators_->compressed_texture_format.GetValues().size(); 4155 if (params) { 4156 for (GLint ii = 0; ii < *num_written; ++ii) { 4157 params[ii] = validators_->compressed_texture_format.GetValues()[ii]; 4158 } 4159 } 4160 return true; 4161 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 4162 *num_written = 1; 4163 if (params) { 4164 *params = validators_->compressed_texture_format.GetValues().size(); 4165 } 4166 return true; 4167 case GL_NUM_SHADER_BINARY_FORMATS: 4168 *num_written = 1; 4169 if (params) { 4170 *params = validators_->shader_binary_format.GetValues().size(); 4171 } 4172 return true; 4173 case GL_SHADER_BINARY_FORMATS: 4174 *num_written = validators_->shader_binary_format.GetValues().size(); 4175 if (params) { 4176 for (GLint ii = 0; ii < *num_written; ++ii) { 4177 params[ii] = validators_->shader_binary_format.GetValues()[ii]; 4178 } 4179 } 4180 return true; 4181 case GL_SHADER_COMPILER: 4182 *num_written = 1; 4183 if (params) { 4184 *params = GL_TRUE; 4185 } 4186 return true; 4187 case GL_ARRAY_BUFFER_BINDING: 4188 *num_written = 1; 4189 if (params) { 4190 if (state_.bound_array_buffer.get()) { 4191 GLuint client_id = 0; 4192 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(), 4193 &client_id); 4194 *params = client_id; 4195 } else { 4196 *params = 0; 4197 } 4198 } 4199 return true; 4200 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 4201 *num_written = 1; 4202 if (params) { 4203 if (state_.vertex_attrib_manager->element_array_buffer()) { 4204 GLuint client_id = 0; 4205 buffer_manager()->GetClientId( 4206 state_.vertex_attrib_manager->element_array_buffer()-> 4207 service_id(), &client_id); 4208 *params = client_id; 4209 } else { 4210 *params = 0; 4211 } 4212 } 4213 return true; 4214 case GL_FRAMEBUFFER_BINDING: 4215 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) 4216 *num_written = 1; 4217 if (params) { 4218 Framebuffer* framebuffer = 4219 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4220 if (framebuffer) { 4221 GLuint client_id = 0; 4222 framebuffer_manager()->GetClientId( 4223 framebuffer->service_id(), &client_id); 4224 *params = client_id; 4225 } else { 4226 *params = 0; 4227 } 4228 } 4229 return true; 4230 case GL_READ_FRAMEBUFFER_BINDING_EXT: 4231 *num_written = 1; 4232 if (params) { 4233 Framebuffer* framebuffer = 4234 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 4235 if (framebuffer) { 4236 GLuint client_id = 0; 4237 framebuffer_manager()->GetClientId( 4238 framebuffer->service_id(), &client_id); 4239 *params = client_id; 4240 } else { 4241 *params = 0; 4242 } 4243 } 4244 return true; 4245 case GL_RENDERBUFFER_BINDING: 4246 *num_written = 1; 4247 if (params) { 4248 Renderbuffer* renderbuffer = 4249 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4250 if (renderbuffer) { 4251 *params = renderbuffer->client_id(); 4252 } else { 4253 *params = 0; 4254 } 4255 } 4256 return true; 4257 case GL_CURRENT_PROGRAM: 4258 *num_written = 1; 4259 if (params) { 4260 if (state_.current_program.get()) { 4261 GLuint client_id = 0; 4262 program_manager()->GetClientId( 4263 state_.current_program->service_id(), &client_id); 4264 *params = client_id; 4265 } else { 4266 *params = 0; 4267 } 4268 } 4269 return true; 4270 case GL_VERTEX_ARRAY_BINDING_OES: 4271 *num_written = 1; 4272 if (params) { 4273 if (state_.vertex_attrib_manager.get() != 4274 default_vertex_attrib_manager_.get()) { 4275 GLuint client_id = 0; 4276 vertex_array_manager_->GetClientId( 4277 state_.vertex_attrib_manager->service_id(), &client_id); 4278 *params = client_id; 4279 } else { 4280 *params = 0; 4281 } 4282 } 4283 return true; 4284 case GL_TEXTURE_BINDING_2D: 4285 *num_written = 1; 4286 if (params) { 4287 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4288 if (unit.bound_texture_2d.get()) { 4289 *params = unit.bound_texture_2d->client_id(); 4290 } else { 4291 *params = 0; 4292 } 4293 } 4294 return true; 4295 case GL_TEXTURE_BINDING_CUBE_MAP: 4296 *num_written = 1; 4297 if (params) { 4298 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4299 if (unit.bound_texture_cube_map.get()) { 4300 *params = unit.bound_texture_cube_map->client_id(); 4301 } else { 4302 *params = 0; 4303 } 4304 } 4305 return true; 4306 case GL_TEXTURE_BINDING_EXTERNAL_OES: 4307 *num_written = 1; 4308 if (params) { 4309 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4310 if (unit.bound_texture_external_oes.get()) { 4311 *params = unit.bound_texture_external_oes->client_id(); 4312 } else { 4313 *params = 0; 4314 } 4315 } 4316 return true; 4317 case GL_TEXTURE_BINDING_RECTANGLE_ARB: 4318 *num_written = 1; 4319 if (params) { 4320 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4321 if (unit.bound_texture_rectangle_arb.get()) { 4322 *params = unit.bound_texture_rectangle_arb->client_id(); 4323 } else { 4324 *params = 0; 4325 } 4326 } 4327 return true; 4328 case GL_UNPACK_FLIP_Y_CHROMIUM: 4329 *num_written = 1; 4330 if (params) { 4331 params[0] = unpack_flip_y_; 4332 } 4333 return true; 4334 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 4335 *num_written = 1; 4336 if (params) { 4337 params[0] = unpack_premultiply_alpha_; 4338 } 4339 return true; 4340 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 4341 *num_written = 1; 4342 if (params) { 4343 params[0] = unpack_unpremultiply_alpha_; 4344 } 4345 return true; 4346 default: 4347 if (pname >= GL_DRAW_BUFFER0_ARB && 4348 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) { 4349 *num_written = 1; 4350 if (params) { 4351 Framebuffer* framebuffer = 4352 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4353 if (framebuffer) { 4354 params[0] = framebuffer->GetDrawBuffer(pname); 4355 } else { // backbuffer 4356 if (pname == GL_DRAW_BUFFER0_ARB) 4357 params[0] = group_->draw_buffer(); 4358 else 4359 params[0] = GL_NONE; 4360 } 4361 } 4362 return true; 4363 } 4364 *num_written = util_.GLGetNumValuesReturned(pname); 4365 return false; 4366 } 4367 } 4368 4369 bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( 4370 GLenum pname, GLsizei* num_values) { 4371 if (state_.GetStateAsGLint(pname, NULL, num_values)) { 4372 return true; 4373 } 4374 return GetHelper(pname, NULL, num_values); 4375 } 4376 4377 GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) { 4378 if (GL_MAX_SAMPLES == pname && 4379 features().use_img_for_multisampled_render_to_texture) { 4380 return GL_MAX_SAMPLES_IMG; 4381 } 4382 return pname; 4383 } 4384 4385 void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { 4386 DCHECK(params); 4387 GLsizei num_written = 0; 4388 if (GetNumValuesReturnedForGLGet(pname, &num_written)) { 4389 scoped_ptr<GLint[]> values(new GLint[num_written]); 4390 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) { 4391 GetHelper(pname, values.get(), &num_written); 4392 } 4393 for (GLsizei ii = 0; ii < num_written; ++ii) { 4394 params[ii] = static_cast<GLboolean>(values[ii]); 4395 } 4396 } else { 4397 pname = AdjustGetPname(pname); 4398 glGetBooleanv(pname, params); 4399 } 4400 } 4401 4402 void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { 4403 DCHECK(params); 4404 GLsizei num_written = 0; 4405 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) { 4406 if (GetHelper(pname, NULL, &num_written)) { 4407 scoped_ptr<GLint[]> values(new GLint[num_written]); 4408 GetHelper(pname, values.get(), &num_written); 4409 for (GLsizei ii = 0; ii < num_written; ++ii) { 4410 params[ii] = static_cast<GLfloat>(values[ii]); 4411 } 4412 } else { 4413 pname = AdjustGetPname(pname); 4414 glGetFloatv(pname, params); 4415 } 4416 } 4417 } 4418 4419 void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { 4420 DCHECK(params); 4421 GLsizei num_written; 4422 if (!state_.GetStateAsGLint(pname, params, &num_written) && 4423 !GetHelper(pname, params, &num_written)) { 4424 pname = AdjustGetPname(pname); 4425 glGetIntegerv(pname, params); 4426 } 4427 } 4428 4429 void GLES2DecoderImpl::DoGetProgramiv( 4430 GLuint program_id, GLenum pname, GLint* params) { 4431 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv"); 4432 if (!program) { 4433 return; 4434 } 4435 program->GetProgramiv(pname, params); 4436 } 4437 4438 void GLES2DecoderImpl::DoGetBufferParameteriv( 4439 GLenum target, GLenum pname, GLint* params) { 4440 // Just delegate it. Some validation is actually done before this. 4441 buffer_manager()->ValidateAndDoGetBufferParameteriv( 4442 &state_, target, pname, params); 4443 } 4444 4445 void GLES2DecoderImpl::DoBindAttribLocation( 4446 GLuint program_id, GLuint index, const char* name) { 4447 if (!StringIsValidForGLES(name)) { 4448 LOCAL_SET_GL_ERROR( 4449 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); 4450 return; 4451 } 4452 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4453 LOCAL_SET_GL_ERROR( 4454 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); 4455 return; 4456 } 4457 if (index >= group_->max_vertex_attribs()) { 4458 LOCAL_SET_GL_ERROR( 4459 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range"); 4460 return; 4461 } 4462 Program* program = GetProgramInfoNotShader( 4463 program_id, "glBindAttribLocation"); 4464 if (!program) { 4465 return; 4466 } 4467 program->SetAttribLocationBinding(name, static_cast<GLint>(index)); 4468 glBindAttribLocation(program->service_id(), index, name); 4469 } 4470 4471 error::Error GLES2DecoderImpl::HandleBindAttribLocation( 4472 uint32 immediate_data_size, const cmds::BindAttribLocation& c) { 4473 GLuint program = static_cast<GLuint>(c.program); 4474 GLuint index = static_cast<GLuint>(c.index); 4475 uint32 name_size = c.data_size; 4476 const char* name = GetSharedMemoryAs<const char*>( 4477 c.name_shm_id, c.name_shm_offset, name_size); 4478 if (name == NULL) { 4479 return error::kOutOfBounds; 4480 } 4481 String name_str(name, name_size); 4482 DoBindAttribLocation(program, index, name_str.c_str()); 4483 return error::kNoError; 4484 } 4485 4486 error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate( 4487 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) { 4488 GLuint program = static_cast<GLuint>(c.program); 4489 GLuint index = static_cast<GLuint>(c.index); 4490 uint32 name_size = c.data_size; 4491 const char* name = GetImmediateDataAs<const char*>( 4492 c, name_size, immediate_data_size); 4493 if (name == NULL) { 4494 return error::kOutOfBounds; 4495 } 4496 String name_str(name, name_size); 4497 DoBindAttribLocation(program, index, name_str.c_str()); 4498 return error::kNoError; 4499 } 4500 4501 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( 4502 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) { 4503 GLuint program = static_cast<GLuint>(c.program); 4504 GLuint index = static_cast<GLuint>(c.index); 4505 Bucket* bucket = GetBucket(c.name_bucket_id); 4506 if (!bucket || bucket->size() == 0) { 4507 return error::kInvalidArguments; 4508 } 4509 std::string name_str; 4510 if (!bucket->GetAsString(&name_str)) { 4511 return error::kInvalidArguments; 4512 } 4513 DoBindAttribLocation(program, index, name_str.c_str()); 4514 return error::kNoError; 4515 } 4516 4517 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM( 4518 GLuint program_id, GLint location, const char* name) { 4519 if (!StringIsValidForGLES(name)) { 4520 LOCAL_SET_GL_ERROR( 4521 GL_INVALID_VALUE, 4522 "glBindUniformLocationCHROMIUM", "Invalid character"); 4523 return; 4524 } 4525 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4526 LOCAL_SET_GL_ERROR( 4527 GL_INVALID_OPERATION, 4528 "glBindUniformLocationCHROMIUM", "reserved prefix"); 4529 return; 4530 } 4531 if (location < 0 || static_cast<uint32>(location) >= 4532 (group_->max_fragment_uniform_vectors() + 4533 group_->max_vertex_uniform_vectors()) * 4) { 4534 LOCAL_SET_GL_ERROR( 4535 GL_INVALID_VALUE, 4536 "glBindUniformLocationCHROMIUM", "location out of range"); 4537 return; 4538 } 4539 Program* program = GetProgramInfoNotShader( 4540 program_id, "glBindUniformLocationCHROMIUM"); 4541 if (!program) { 4542 return; 4543 } 4544 if (!program->SetUniformLocationBinding(name, location)) { 4545 LOCAL_SET_GL_ERROR( 4546 GL_INVALID_VALUE, 4547 "glBindUniformLocationCHROMIUM", "location out of range"); 4548 } 4549 } 4550 4551 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM( 4552 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) { 4553 GLuint program = static_cast<GLuint>(c.program); 4554 GLint location = static_cast<GLint>(c.location); 4555 uint32 name_size = c.data_size; 4556 const char* name = GetSharedMemoryAs<const char*>( 4557 c.name_shm_id, c.name_shm_offset, name_size); 4558 if (name == NULL) { 4559 return error::kOutOfBounds; 4560 } 4561 String name_str(name, name_size); 4562 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4563 return error::kNoError; 4564 } 4565 4566 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate( 4567 uint32 immediate_data_size, 4568 const cmds::BindUniformLocationCHROMIUMImmediate& c) { 4569 GLuint program = static_cast<GLuint>(c.program); 4570 GLint location = static_cast<GLint>(c.location); 4571 uint32 name_size = c.data_size; 4572 const char* name = GetImmediateDataAs<const char*>( 4573 c, name_size, immediate_data_size); 4574 if (name == NULL) { 4575 return error::kOutOfBounds; 4576 } 4577 String name_str(name, name_size); 4578 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4579 return error::kNoError; 4580 } 4581 4582 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket( 4583 uint32 immediate_data_size, 4584 const cmds::BindUniformLocationCHROMIUMBucket& c) { 4585 GLuint program = static_cast<GLuint>(c.program); 4586 GLint location = static_cast<GLint>(c.location); 4587 Bucket* bucket = GetBucket(c.name_bucket_id); 4588 if (!bucket || bucket->size() == 0) { 4589 return error::kInvalidArguments; 4590 } 4591 std::string name_str; 4592 if (!bucket->GetAsString(&name_str)) { 4593 return error::kInvalidArguments; 4594 } 4595 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4596 return error::kNoError; 4597 } 4598 4599 error::Error GLES2DecoderImpl::HandleDeleteShader( 4600 uint32 immediate_data_size, const cmds::DeleteShader& c) { 4601 GLuint client_id = c.shader; 4602 if (client_id) { 4603 Shader* shader = GetShader(client_id); 4604 if (shader) { 4605 if (!shader->IsDeleted()) { 4606 glDeleteShader(shader->service_id()); 4607 shader_manager()->MarkAsDeleted(shader); 4608 } 4609 } else { 4610 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader"); 4611 } 4612 } 4613 return error::kNoError; 4614 } 4615 4616 error::Error GLES2DecoderImpl::HandleDeleteProgram( 4617 uint32 immediate_data_size, const cmds::DeleteProgram& c) { 4618 GLuint client_id = c.program; 4619 if (client_id) { 4620 Program* program = GetProgram(client_id); 4621 if (program) { 4622 if (!program->IsDeleted()) { 4623 program_manager()->MarkAsDeleted(shader_manager(), program); 4624 } 4625 } else { 4626 LOCAL_SET_GL_ERROR( 4627 GL_INVALID_VALUE, "glDeleteProgram", "unknown program"); 4628 } 4629 } 4630 return error::kNoError; 4631 } 4632 4633 void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM( 4634 GLuint namespace_id, GLsizei n, const GLuint* ids) { 4635 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4636 for (GLsizei ii = 0; ii < n; ++ii) { 4637 id_allocator->FreeID(ids[ii]); 4638 } 4639 } 4640 4641 error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM( 4642 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) { 4643 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4644 GLsizei n = static_cast<GLsizei>(c.n); 4645 uint32 data_size; 4646 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4647 return error::kOutOfBounds; 4648 } 4649 const GLuint* ids = GetSharedMemoryAs<const GLuint*>( 4650 c.ids_shm_id, c.ids_shm_offset, data_size); 4651 if (n < 0) { 4652 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0"); 4653 return error::kNoError; 4654 } 4655 if (ids == NULL) { 4656 return error::kOutOfBounds; 4657 } 4658 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids); 4659 return error::kNoError; 4660 } 4661 4662 void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM( 4663 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { 4664 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4665 if (id_offset == 0) { 4666 for (GLsizei ii = 0; ii < n; ++ii) { 4667 ids[ii] = id_allocator->AllocateID(); 4668 } 4669 } else { 4670 for (GLsizei ii = 0; ii < n; ++ii) { 4671 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset); 4672 id_offset = ids[ii] + 1; 4673 } 4674 } 4675 } 4676 4677 error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM( 4678 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) { 4679 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4680 GLuint id_offset = static_cast<GLuint>(c.id_offset); 4681 GLsizei n = static_cast<GLsizei>(c.n); 4682 uint32 data_size; 4683 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4684 return error::kOutOfBounds; 4685 } 4686 GLuint* ids = GetSharedMemoryAs<GLuint*>( 4687 c.ids_shm_id, c.ids_shm_offset, data_size); 4688 if (n < 0) { 4689 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0"); 4690 return error::kNoError; 4691 } 4692 if (ids == NULL) { 4693 return error::kOutOfBounds; 4694 } 4695 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids); 4696 return error::kNoError; 4697 } 4698 4699 void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM( 4700 GLuint namespace_id, GLsizei n, const GLuint* ids) { 4701 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4702 for (GLsizei ii = 0; ii < n; ++ii) { 4703 if (!id_allocator->MarkAsUsed(ids[ii])) { 4704 for (GLsizei jj = 0; jj < ii; ++jj) { 4705 id_allocator->FreeID(ids[jj]); 4706 } 4707 LOCAL_SET_GL_ERROR( 4708 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", 4709 "attempt to register id that already exists"); 4710 return; 4711 } 4712 } 4713 } 4714 4715 error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM( 4716 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) { 4717 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4718 GLsizei n = static_cast<GLsizei>(c.n); 4719 uint32 data_size; 4720 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4721 return error::kOutOfBounds; 4722 } 4723 GLuint* ids = GetSharedMemoryAs<GLuint*>( 4724 c.ids_shm_id, c.ids_shm_offset, data_size); 4725 if (n < 0) { 4726 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0"); 4727 return error::kNoError; 4728 } 4729 if (ids == NULL) { 4730 return error::kOutOfBounds; 4731 } 4732 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids); 4733 return error::kNoError; 4734 } 4735 4736 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { 4737 DCHECK(!ShouldDeferDraws()); 4738 if (CheckBoundFramebuffersValid("glClear")) { 4739 ApplyDirtyState(); 4740 glClear(mask); 4741 } 4742 return error::kNoError; 4743 } 4744 4745 void GLES2DecoderImpl::DoFramebufferRenderbuffer( 4746 GLenum target, GLenum attachment, GLenum renderbuffertarget, 4747 GLuint client_renderbuffer_id) { 4748 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 4749 if (!framebuffer) { 4750 LOCAL_SET_GL_ERROR( 4751 GL_INVALID_OPERATION, 4752 "glFramebufferRenderbuffer", "no framebuffer bound"); 4753 return; 4754 } 4755 GLuint service_id = 0; 4756 Renderbuffer* renderbuffer = NULL; 4757 if (client_renderbuffer_id) { 4758 renderbuffer = GetRenderbuffer(client_renderbuffer_id); 4759 if (!renderbuffer) { 4760 LOCAL_SET_GL_ERROR( 4761 GL_INVALID_OPERATION, 4762 "glFramebufferRenderbuffer", "unknown renderbuffer"); 4763 return; 4764 } 4765 service_id = renderbuffer->service_id(); 4766 } 4767 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer"); 4768 glFramebufferRenderbufferEXT( 4769 target, attachment, renderbuffertarget, service_id); 4770 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer"); 4771 if (error == GL_NO_ERROR) { 4772 framebuffer->AttachRenderbuffer(attachment, renderbuffer); 4773 } 4774 if (framebuffer == state_.bound_draw_framebuffer.get()) { 4775 clear_state_dirty_ = true; 4776 } 4777 OnFboChanged(); 4778 } 4779 4780 void GLES2DecoderImpl::DoDisable(GLenum cap) { 4781 if (SetCapabilityState(cap, false)) { 4782 glDisable(cap); 4783 } 4784 } 4785 4786 void GLES2DecoderImpl::DoEnable(GLenum cap) { 4787 if (SetCapabilityState(cap, true)) { 4788 glEnable(cap); 4789 } 4790 } 4791 4792 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) { 4793 state_.z_near = std::min(1.0f, std::max(0.0f, znear)); 4794 state_.z_far = std::min(1.0f, std::max(0.0f, zfar)); 4795 glDepthRange(znear, zfar); 4796 } 4797 4798 void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) { 4799 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value)); 4800 state_.sample_coverage_invert = (invert != 0); 4801 glSampleCoverage(state_.sample_coverage_value, invert); 4802 } 4803 4804 // Assumes framebuffer is complete. 4805 void GLES2DecoderImpl::ClearUnclearedAttachments( 4806 GLenum target, Framebuffer* framebuffer) { 4807 if (target == GL_READ_FRAMEBUFFER_EXT) { 4808 // bind this to the DRAW point, clear then bind back to READ 4809 // TODO(gman): I don't think there is any guarantee that an FBO that 4810 // is complete on the READ attachment will be complete as a DRAW 4811 // attachment. 4812 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); 4813 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id()); 4814 } 4815 GLbitfield clear_bits = 0; 4816 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) { 4817 glClearColor( 4818 0.0f, 0.0f, 0.0f, 4819 (GLES2Util::GetChannelsForFormat( 4820 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 4821 1.0f); 4822 glColorMask(true, true, true, true); 4823 clear_bits |= GL_COLOR_BUFFER_BIT; 4824 } 4825 4826 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || 4827 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 4828 glClearStencil(0); 4829 glStencilMask(-1); 4830 clear_bits |= GL_STENCIL_BUFFER_BIT; 4831 } 4832 4833 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || 4834 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 4835 glClearDepth(1.0f); 4836 glDepthMask(true); 4837 clear_bits |= GL_DEPTH_BUFFER_BIT; 4838 } 4839 4840 glDisable(GL_SCISSOR_TEST); 4841 glClear(clear_bits); 4842 4843 framebuffer_manager()->MarkAttachmentsAsCleared( 4844 framebuffer, renderbuffer_manager(), texture_manager()); 4845 4846 RestoreClearState(); 4847 4848 if (target == GL_READ_FRAMEBUFFER_EXT) { 4849 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id()); 4850 Framebuffer* draw_framebuffer = 4851 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 4852 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() : 4853 GetBackbufferServiceId(); 4854 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id); 4855 } 4856 } 4857 4858 void GLES2DecoderImpl::RestoreClearState() { 4859 clear_state_dirty_ = true; 4860 glClearColor( 4861 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue, 4862 state_.color_clear_alpha); 4863 glClearStencil(state_.stencil_clear); 4864 glClearDepth(state_.depth_clear); 4865 if (state_.enable_flags.scissor_test) { 4866 glEnable(GL_SCISSOR_TEST); 4867 } 4868 } 4869 4870 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { 4871 Framebuffer* framebuffer = 4872 GetFramebufferInfoForTarget(target); 4873 if (!framebuffer) { 4874 return GL_FRAMEBUFFER_COMPLETE; 4875 } 4876 GLenum completeness = framebuffer->IsPossiblyComplete(); 4877 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 4878 return completeness; 4879 } 4880 return framebuffer->GetStatus(texture_manager(), target); 4881 } 4882 4883 void GLES2DecoderImpl::DoFramebufferTexture2D( 4884 GLenum target, GLenum attachment, GLenum textarget, 4885 GLuint client_texture_id, GLint level) { 4886 DoFramebufferTexture2DCommon( 4887 "glFramebufferTexture2D", target, attachment, 4888 textarget, client_texture_id, level, 0); 4889 } 4890 4891 void GLES2DecoderImpl::DoFramebufferTexture2DMultisample( 4892 GLenum target, GLenum attachment, GLenum textarget, 4893 GLuint client_texture_id, GLint level, GLsizei samples) { 4894 if (!features().multisampled_render_to_texture) { 4895 LOCAL_SET_GL_ERROR( 4896 GL_INVALID_OPERATION, 4897 "glFramebufferTexture2DMultisample", "function not available"); 4898 return; 4899 } 4900 DoFramebufferTexture2DCommon( 4901 "glFramebufferTexture2DMultisample", target, attachment, 4902 textarget, client_texture_id, level, samples); 4903 } 4904 4905 void GLES2DecoderImpl::DoFramebufferTexture2DCommon( 4906 const char* name, GLenum target, GLenum attachment, GLenum textarget, 4907 GLuint client_texture_id, GLint level, GLsizei samples) { 4908 if (samples > renderbuffer_manager()->max_samples()) { 4909 LOCAL_SET_GL_ERROR( 4910 GL_INVALID_VALUE, 4911 "glFramebufferTexture2DMultisample", "samples too large"); 4912 return; 4913 } 4914 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 4915 if (!framebuffer) { 4916 LOCAL_SET_GL_ERROR( 4917 GL_INVALID_OPERATION, 4918 name, "no framebuffer bound."); 4919 return; 4920 } 4921 GLuint service_id = 0; 4922 TextureRef* texture_ref = NULL; 4923 if (client_texture_id) { 4924 texture_ref = GetTexture(client_texture_id); 4925 if (!texture_ref) { 4926 LOCAL_SET_GL_ERROR( 4927 GL_INVALID_OPERATION, 4928 name, "unknown texture_ref"); 4929 return; 4930 } 4931 service_id = texture_ref->service_id(); 4932 } 4933 4934 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) { 4935 LOCAL_SET_GL_ERROR( 4936 GL_INVALID_VALUE, 4937 name, "level out of range"); 4938 return; 4939 } 4940 4941 if (texture_ref) 4942 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget); 4943 4944 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name); 4945 if (0 == samples) { 4946 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); 4947 } else { 4948 if (features().use_img_for_multisampled_render_to_texture) { 4949 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, 4950 service_id, level, samples); 4951 } else { 4952 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, 4953 service_id, level, samples); 4954 } 4955 } 4956 GLenum error = LOCAL_PEEK_GL_ERROR(name); 4957 if (error == GL_NO_ERROR) { 4958 framebuffer->AttachTexture(attachment, texture_ref, textarget, level, 4959 samples); 4960 } 4961 if (framebuffer == state_.bound_draw_framebuffer.get()) { 4962 clear_state_dirty_ = true; 4963 } 4964 4965 if (texture_ref) 4966 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget); 4967 4968 OnFboChanged(); 4969 } 4970 4971 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( 4972 GLenum target, GLenum attachment, GLenum pname, GLint* params) { 4973 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 4974 if (!framebuffer) { 4975 LOCAL_SET_GL_ERROR( 4976 GL_INVALID_OPERATION, 4977 "glFramebufferAttachmentParameteriv", "no framebuffer bound"); 4978 return; 4979 } 4980 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { 4981 const Framebuffer::Attachment* attachment_object = 4982 framebuffer->GetAttachment(attachment); 4983 *params = attachment_object ? attachment_object->object_name() : 0; 4984 } else { 4985 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT && 4986 features().use_img_for_multisampled_render_to_texture) { 4987 pname = GL_TEXTURE_SAMPLES_IMG; 4988 } 4989 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); 4990 } 4991 } 4992 4993 void GLES2DecoderImpl::DoGetRenderbufferParameteriv( 4994 GLenum target, GLenum pname, GLint* params) { 4995 Renderbuffer* renderbuffer = 4996 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4997 if (!renderbuffer) { 4998 LOCAL_SET_GL_ERROR( 4999 GL_INVALID_OPERATION, 5000 "glGetRenderbufferParameteriv", "no renderbuffer bound"); 5001 return; 5002 } 5003 switch (pname) { 5004 case GL_RENDERBUFFER_INTERNAL_FORMAT: 5005 *params = renderbuffer->internal_format(); 5006 break; 5007 case GL_RENDERBUFFER_WIDTH: 5008 *params = renderbuffer->width(); 5009 break; 5010 case GL_RENDERBUFFER_HEIGHT: 5011 *params = renderbuffer->height(); 5012 break; 5013 case GL_RENDERBUFFER_SAMPLES_EXT: 5014 if (features().use_img_for_multisampled_render_to_texture) { 5015 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG, 5016 params); 5017 } else { 5018 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT, 5019 params); 5020 } 5021 default: 5022 glGetRenderbufferParameterivEXT(target, pname, params); 5023 break; 5024 } 5025 } 5026 5027 void GLES2DecoderImpl::DoBlitFramebufferEXT( 5028 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 5029 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 5030 GLbitfield mask, GLenum filter) { 5031 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws()); 5032 if (!features().chromium_framebuffer_multisample) { 5033 LOCAL_SET_GL_ERROR( 5034 GL_INVALID_OPERATION, 5035 "glBlitFramebufferEXT", "function not available"); 5036 } 5037 5038 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) { 5039 return; 5040 } 5041 5042 glDisable(GL_SCISSOR_TEST); 5043 if (IsAngle()) { 5044 glBlitFramebufferANGLE( 5045 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5046 } else { 5047 glBlitFramebufferEXT( 5048 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5049 } 5050 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); 5051 } 5052 5053 void GLES2DecoderImpl::DoRenderbufferStorageMultisample( 5054 GLenum target, GLsizei samples, GLenum internalformat, 5055 GLsizei width, GLsizei height) { 5056 if (!features().chromium_framebuffer_multisample && 5057 !features().multisampled_render_to_texture) { 5058 LOCAL_SET_GL_ERROR( 5059 GL_INVALID_OPERATION, 5060 "glRenderbufferStorageMultisample", "function not available"); 5061 return; 5062 } 5063 5064 Renderbuffer* renderbuffer = 5065 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5066 if (!renderbuffer) { 5067 LOCAL_SET_GL_ERROR( 5068 GL_INVALID_OPERATION, 5069 "glRenderbufferStorageMultisample", "no renderbuffer bound"); 5070 return; 5071 } 5072 5073 if (samples > renderbuffer_manager()->max_samples()) { 5074 LOCAL_SET_GL_ERROR( 5075 GL_INVALID_VALUE, 5076 "glRenderbufferStorageMultisample", "samples too large"); 5077 return; 5078 } 5079 5080 if (width > renderbuffer_manager()->max_renderbuffer_size() || 5081 height > renderbuffer_manager()->max_renderbuffer_size()) { 5082 LOCAL_SET_GL_ERROR( 5083 GL_INVALID_VALUE, 5084 "glRenderbufferStorageMultisample", "dimensions too large"); 5085 return; 5086 } 5087 5088 uint32 estimated_size = 0; 5089 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize( 5090 width, height, samples, internalformat, &estimated_size)) { 5091 LOCAL_SET_GL_ERROR( 5092 GL_OUT_OF_MEMORY, 5093 "glRenderbufferStorageMultsample", "dimensions too large"); 5094 return; 5095 } 5096 5097 if (!EnsureGPUMemoryAvailable(estimated_size)) { 5098 LOCAL_SET_GL_ERROR( 5099 GL_OUT_OF_MEMORY, 5100 "glRenderbufferStorageMultsample", "out of memory"); 5101 return; 5102 } 5103 5104 GLenum impl_format = RenderbufferManager:: 5105 InternalRenderbufferFormatToImplFormat(internalformat); 5106 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample"); 5107 if (IsAngle()) { 5108 glRenderbufferStorageMultisampleANGLE( 5109 target, samples, impl_format, width, height); 5110 } else if (features().use_img_for_multisampled_render_to_texture) { 5111 glRenderbufferStorageMultisampleIMG( 5112 target, samples, impl_format, width, height); 5113 } else { 5114 glRenderbufferStorageMultisampleEXT( 5115 target, samples, impl_format, width, height); 5116 } 5117 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample"); 5118 if (error == GL_NO_ERROR) { 5119 // TODO(gman): If renderbuffers tracked which framebuffers they were 5120 // attached to we could just mark those framebuffers as not complete. 5121 framebuffer_manager()->IncFramebufferStateChangeCount(); 5122 renderbuffer_manager()->SetInfo( 5123 renderbuffer, samples, internalformat, width, height); 5124 } 5125 } 5126 5127 void GLES2DecoderImpl::DoRenderbufferStorage( 5128 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { 5129 Renderbuffer* renderbuffer = 5130 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5131 if (!renderbuffer) { 5132 LOCAL_SET_GL_ERROR( 5133 GL_INVALID_OPERATION, 5134 "glRenderbufferStorage", "no renderbuffer bound"); 5135 return; 5136 } 5137 5138 if (width > renderbuffer_manager()->max_renderbuffer_size() || 5139 height > renderbuffer_manager()->max_renderbuffer_size()) { 5140 LOCAL_SET_GL_ERROR( 5141 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large"); 5142 return; 5143 } 5144 5145 uint32 estimated_size = 0; 5146 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize( 5147 width, height, 1, internalformat, &estimated_size)) { 5148 LOCAL_SET_GL_ERROR( 5149 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large"); 5150 return; 5151 } 5152 5153 if (!EnsureGPUMemoryAvailable(estimated_size)) { 5154 LOCAL_SET_GL_ERROR( 5155 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory"); 5156 return; 5157 } 5158 5159 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage"); 5160 glRenderbufferStorageEXT( 5161 target, RenderbufferManager:: 5162 InternalRenderbufferFormatToImplFormat(internalformat), 5163 width, height); 5164 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage"); 5165 if (error == GL_NO_ERROR) { 5166 // TODO(gman): If tetxures tracked which framebuffers they were attached to 5167 // we could just mark those framebuffers as not complete. 5168 framebuffer_manager()->IncFramebufferStateChangeCount(); 5169 renderbuffer_manager()->SetInfo( 5170 renderbuffer, 1, internalformat, width, height); 5171 } 5172 } 5173 5174 void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { 5175 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram"); 5176 Program* program = GetProgramInfoNotShader( 5177 program_id, "glLinkProgram"); 5178 if (!program) { 5179 return; 5180 } 5181 5182 LogClientServiceForInfo(program, program_id, "glLinkProgram"); 5183 ShaderTranslator* vertex_translator = NULL; 5184 ShaderTranslator* fragment_translator = NULL; 5185 if (use_shader_translator_) { 5186 vertex_translator = vertex_translator_.get(); 5187 fragment_translator = fragment_translator_.get(); 5188 } 5189 if (program->Link(shader_manager(), 5190 vertex_translator, 5191 fragment_translator, 5192 feature_info_.get(), 5193 shader_cache_callback_)) { 5194 if (program == state_.current_program.get()) { 5195 if (workarounds().use_current_program_after_successful_link) { 5196 glUseProgram(program->service_id()); 5197 } 5198 program_manager()->ClearUniforms(program); 5199 } 5200 } 5201 }; 5202 5203 void GLES2DecoderImpl::DoTexParameterf( 5204 GLenum target, GLenum pname, GLfloat param) { 5205 TextureRef* texture = GetTextureInfoForTarget(target); 5206 if (!texture) { 5207 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture"); 5208 return; 5209 } 5210 5211 texture_manager()->SetParameter( 5212 "glTexParameterf", GetErrorState(), texture, pname, 5213 static_cast<GLint>(param)); 5214 } 5215 5216 void GLES2DecoderImpl::DoTexParameteri( 5217 GLenum target, GLenum pname, GLint param) { 5218 TextureRef* texture = GetTextureInfoForTarget(target); 5219 if (!texture) { 5220 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture"); 5221 return; 5222 } 5223 5224 texture_manager()->SetParameter( 5225 "glTexParameteri", GetErrorState(), texture, pname, param); 5226 } 5227 5228 void GLES2DecoderImpl::DoTexParameterfv( 5229 GLenum target, GLenum pname, const GLfloat* params) { 5230 TextureRef* texture = GetTextureInfoForTarget(target); 5231 if (!texture) { 5232 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture"); 5233 return; 5234 } 5235 5236 texture_manager()->SetParameter( 5237 "glTexParameterfv", GetErrorState(), texture, pname, 5238 static_cast<GLint>(params[0])); 5239 } 5240 5241 void GLES2DecoderImpl::DoTexParameteriv( 5242 GLenum target, GLenum pname, const GLint* params) { 5243 TextureRef* texture = GetTextureInfoForTarget(target); 5244 if (!texture) { 5245 LOCAL_SET_GL_ERROR( 5246 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture"); 5247 return; 5248 } 5249 5250 texture_manager()->SetParameter( 5251 "glTexParameteriv", GetErrorState(), texture, pname, *params); 5252 } 5253 5254 bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) { 5255 if (!state_.current_program.get()) { 5256 // The program does not exist. 5257 LOCAL_SET_GL_ERROR( 5258 GL_INVALID_OPERATION, function_name, "no program in use"); 5259 return false; 5260 } 5261 if (!state_.current_program->InUse()) { 5262 LOCAL_SET_GL_ERROR( 5263 GL_INVALID_OPERATION, function_name, "program not linked"); 5264 return false; 5265 } 5266 return true; 5267 } 5268 5269 bool GLES2DecoderImpl::CheckCurrentProgramForUniform( 5270 GLint location, const char* function_name) { 5271 if (!CheckCurrentProgram(function_name)) { 5272 return false; 5273 } 5274 return location != -1; 5275 } 5276 5277 namespace { 5278 5279 static const GLenum valid_int_vec1_types_list[] = { 5280 GL_INT, 5281 GL_BOOL, 5282 GL_SAMPLER_2D, 5283 GL_SAMPLER_2D_RECT_ARB, 5284 GL_SAMPLER_CUBE, 5285 GL_SAMPLER_EXTERNAL_OES, 5286 }; 5287 5288 static const GLenum valid_int_vec2_types_list[] = { 5289 GL_INT_VEC2, 5290 GL_BOOL_VEC2, 5291 }; 5292 5293 static const GLenum valid_int_vec3_types_list[] = { 5294 GL_INT_VEC3, 5295 GL_BOOL_VEC3, 5296 }; 5297 5298 static const GLenum valid_int_vec4_types_list[] = { 5299 GL_INT_VEC4, 5300 GL_BOOL_VEC4, 5301 }; 5302 5303 static const GLenum valid_float_vec1_types_list[] = { 5304 GL_FLOAT, 5305 GL_BOOL, 5306 }; 5307 5308 static const GLenum valid_float_vec2_types_list[] = { 5309 GL_FLOAT_VEC2, 5310 GL_BOOL_VEC2, 5311 }; 5312 5313 static const GLenum valid_float_vec3_types_list[] = { 5314 GL_FLOAT_VEC3, 5315 GL_BOOL_VEC3, 5316 }; 5317 5318 static const GLenum valid_float_vec4_types_list[] = { 5319 GL_FLOAT_VEC4, 5320 GL_BOOL_VEC4, 5321 }; 5322 5323 static const GLenum valid_float_mat2_types_list[] = { 5324 GL_FLOAT_MAT2, 5325 }; 5326 5327 static const GLenum valid_float_mat3_types_list[] = { 5328 GL_FLOAT_MAT3, 5329 }; 5330 5331 static const GLenum valid_float_mat4_types_list[] = { 5332 GL_FLOAT_MAT4, 5333 }; 5334 5335 static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = { 5336 valid_int_vec1_types_list, 5337 arraysize(valid_int_vec1_types_list), 5338 }; 5339 5340 static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = { 5341 valid_int_vec2_types_list, 5342 arraysize(valid_int_vec2_types_list), 5343 }; 5344 5345 static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = { 5346 valid_int_vec3_types_list, 5347 arraysize(valid_int_vec3_types_list), 5348 }; 5349 5350 static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = { 5351 valid_int_vec4_types_list, 5352 arraysize(valid_int_vec4_types_list), 5353 }; 5354 5355 static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = { 5356 valid_float_vec1_types_list, 5357 arraysize(valid_float_vec1_types_list), 5358 }; 5359 5360 static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = { 5361 valid_float_vec2_types_list, 5362 arraysize(valid_float_vec2_types_list), 5363 }; 5364 5365 static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = { 5366 valid_float_vec3_types_list, 5367 arraysize(valid_float_vec3_types_list), 5368 }; 5369 5370 static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = { 5371 valid_float_vec4_types_list, 5372 arraysize(valid_float_vec4_types_list), 5373 }; 5374 5375 static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = { 5376 valid_float_mat2_types_list, 5377 arraysize(valid_float_mat2_types_list), 5378 }; 5379 5380 static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = { 5381 valid_float_mat3_types_list, 5382 arraysize(valid_float_mat3_types_list), 5383 }; 5384 5385 static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = { 5386 valid_float_mat4_types_list, 5387 arraysize(valid_float_mat4_types_list), 5388 }; 5389 5390 } // anonymous namespace. 5391 5392 bool GLES2DecoderImpl::PrepForSetUniformByLocation( 5393 GLint fake_location, const char* function_name, 5394 const GLES2DecoderImpl::BaseUniformInfo& base_info, 5395 GLint* real_location, GLenum* type, GLsizei* count) { 5396 DCHECK(type); 5397 DCHECK(count); 5398 DCHECK(real_location); 5399 5400 if (!CheckCurrentProgramForUniform(fake_location, function_name)) { 5401 return false; 5402 } 5403 GLint array_index = -1; 5404 const Program::UniformInfo* info = 5405 state_.current_program->GetUniformInfoByFakeLocation( 5406 fake_location, real_location, &array_index); 5407 if (!info) { 5408 LOCAL_SET_GL_ERROR( 5409 GL_INVALID_OPERATION, function_name, "unknown location"); 5410 return false; 5411 } 5412 bool okay = false; 5413 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) { 5414 if (base_info.valid_types[ii] == info->type) { 5415 okay = true; 5416 break; 5417 } 5418 } 5419 if (!okay) { 5420 LOCAL_SET_GL_ERROR( 5421 GL_INVALID_OPERATION, function_name, 5422 "wrong uniform function for type"); 5423 return false; 5424 } 5425 if (*count > 1 && !info->is_array) { 5426 LOCAL_SET_GL_ERROR( 5427 GL_INVALID_OPERATION, function_name, "count > 1 for non-array"); 5428 return false; 5429 } 5430 *count = std::min(info->size - array_index, *count); 5431 if (*count <= 0) { 5432 return false; 5433 } 5434 *type = info->type; 5435 return true; 5436 } 5437 5438 void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) { 5439 GLenum type = 0; 5440 GLsizei count = 1; 5441 GLint real_location = -1; 5442 if (!PrepForSetUniformByLocation( 5443 fake_location, "glUniform1iv", valid_int_vec1_base_info, 5444 &real_location, &type, &count)) { 5445 return; 5446 } 5447 if (!state_.current_program->SetSamplers( 5448 state_.texture_units.size(), fake_location, 1, &v0)) { 5449 LOCAL_SET_GL_ERROR( 5450 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range"); 5451 return; 5452 } 5453 glUniform1i(real_location, v0); 5454 } 5455 5456 void GLES2DecoderImpl::DoUniform1iv( 5457 GLint fake_location, GLsizei count, const GLint *value) { 5458 GLenum type = 0; 5459 GLint real_location = -1; 5460 if (!PrepForSetUniformByLocation( 5461 fake_location, "glUniform1iv", valid_int_vec1_base_info, 5462 &real_location, &type, &count)) { 5463 return; 5464 } 5465 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB || 5466 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) { 5467 if (!state_.current_program->SetSamplers( 5468 state_.texture_units.size(), fake_location, count, value)) { 5469 LOCAL_SET_GL_ERROR( 5470 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range"); 5471 return; 5472 } 5473 } 5474 glUniform1iv(real_location, count, value); 5475 } 5476 5477 void GLES2DecoderImpl::DoUniform1fv( 5478 GLint fake_location, GLsizei count, const GLfloat* value) { 5479 GLenum type = 0; 5480 GLint real_location = -1; 5481 if (!PrepForSetUniformByLocation( 5482 fake_location, "glUniform1fv", valid_float_vec1_base_info, 5483 &real_location, &type, &count)) { 5484 return; 5485 } 5486 if (type == GL_BOOL) { 5487 scoped_ptr<GLint[]> temp(new GLint[count]); 5488 for (GLsizei ii = 0; ii < count; ++ii) { 5489 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5490 } 5491 DoUniform1iv(real_location, count, temp.get()); 5492 } else { 5493 glUniform1fv(real_location, count, value); 5494 } 5495 } 5496 5497 void GLES2DecoderImpl::DoUniform2fv( 5498 GLint fake_location, GLsizei count, const GLfloat* value) { 5499 GLenum type = 0; 5500 GLint real_location = -1; 5501 if (!PrepForSetUniformByLocation( 5502 fake_location, "glUniform2fv", valid_float_vec2_base_info, 5503 &real_location, &type, &count)) { 5504 return; 5505 } 5506 if (type == GL_BOOL_VEC2) { 5507 GLsizei num_values = count * 2; 5508 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5509 for (GLsizei ii = 0; ii < num_values; ++ii) { 5510 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5511 } 5512 glUniform2iv(real_location, count, temp.get()); 5513 } else { 5514 glUniform2fv(real_location, count, value); 5515 } 5516 } 5517 5518 void GLES2DecoderImpl::DoUniform3fv( 5519 GLint fake_location, GLsizei count, const GLfloat* value) { 5520 GLenum type = 0; 5521 GLint real_location = -1; 5522 if (!PrepForSetUniformByLocation( 5523 fake_location, "glUniform3fv", valid_float_vec3_base_info, 5524 &real_location, &type, &count)) { 5525 return; 5526 } 5527 if (type == GL_BOOL_VEC3) { 5528 GLsizei num_values = count * 3; 5529 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5530 for (GLsizei ii = 0; ii < num_values; ++ii) { 5531 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5532 } 5533 glUniform3iv(real_location, count, temp.get()); 5534 } else { 5535 glUniform3fv(real_location, count, value); 5536 } 5537 } 5538 5539 void GLES2DecoderImpl::DoUniform4fv( 5540 GLint fake_location, GLsizei count, const GLfloat* value) { 5541 GLenum type = 0; 5542 GLint real_location = -1; 5543 if (!PrepForSetUniformByLocation( 5544 fake_location, "glUniform4fv", valid_float_vec4_base_info, 5545 &real_location, &type, &count)) { 5546 return; 5547 } 5548 if (type == GL_BOOL_VEC4) { 5549 GLsizei num_values = count * 4; 5550 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5551 for (GLsizei ii = 0; ii < num_values; ++ii) { 5552 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5553 } 5554 glUniform4iv(real_location, count, temp.get()); 5555 } else { 5556 glUniform4fv(real_location, count, value); 5557 } 5558 } 5559 5560 void GLES2DecoderImpl::DoUniform2iv( 5561 GLint fake_location, GLsizei count, const GLint* value) { 5562 GLenum type = 0; 5563 GLint real_location = -1; 5564 if (!PrepForSetUniformByLocation( 5565 fake_location, "glUniform2iv", valid_int_vec2_base_info, 5566 &real_location, &type, &count)) { 5567 return; 5568 } 5569 glUniform2iv(real_location, count, value); 5570 } 5571 5572 void GLES2DecoderImpl::DoUniform3iv( 5573 GLint fake_location, GLsizei count, const GLint* value) { 5574 GLenum type = 0; 5575 GLint real_location = -1; 5576 if (!PrepForSetUniformByLocation( 5577 fake_location, "glUniform3iv", valid_int_vec3_base_info, 5578 &real_location, &type, &count)) { 5579 return; 5580 } 5581 glUniform3iv(real_location, count, value); 5582 } 5583 5584 void GLES2DecoderImpl::DoUniform4iv( 5585 GLint fake_location, GLsizei count, const GLint* value) { 5586 GLenum type = 0; 5587 GLint real_location = -1; 5588 if (!PrepForSetUniformByLocation( 5589 fake_location, "glUniform4iv", valid_int_vec4_base_info, 5590 &real_location, &type, &count)) { 5591 return; 5592 } 5593 glUniform4iv(real_location, count, value); 5594 } 5595 5596 void GLES2DecoderImpl::DoUniformMatrix2fv( 5597 GLint fake_location, GLsizei count, GLboolean transpose, 5598 const GLfloat* value) { 5599 GLenum type = 0; 5600 GLint real_location = -1; 5601 if (!PrepForSetUniformByLocation( 5602 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info, 5603 &real_location, &type, &count)) { 5604 return; 5605 } 5606 glUniformMatrix2fv(real_location, count, transpose, value); 5607 } 5608 5609 void GLES2DecoderImpl::DoUniformMatrix3fv( 5610 GLint fake_location, GLsizei count, GLboolean transpose, 5611 const GLfloat* value) { 5612 GLenum type = 0; 5613 GLint real_location = -1; 5614 if (!PrepForSetUniformByLocation( 5615 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info, 5616 &real_location, &type, &count)) { 5617 return; 5618 } 5619 glUniformMatrix3fv(real_location, count, transpose, value); 5620 } 5621 5622 void GLES2DecoderImpl::DoUniformMatrix4fv( 5623 GLint fake_location, GLsizei count, GLboolean transpose, 5624 const GLfloat* value) { 5625 GLenum type = 0; 5626 GLint real_location = -1; 5627 if (!PrepForSetUniformByLocation( 5628 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info, 5629 &real_location, &type, &count)) { 5630 return; 5631 } 5632 glUniformMatrix4fv(real_location, count, transpose, value); 5633 } 5634 5635 void GLES2DecoderImpl::DoUseProgram(GLuint program_id) { 5636 GLuint service_id = 0; 5637 Program* program = NULL; 5638 if (program_id) { 5639 program = GetProgramInfoNotShader(program_id, "glUseProgram"); 5640 if (!program) { 5641 return; 5642 } 5643 if (!program->IsValid()) { 5644 // Program was not linked successfully. (ie, glLinkProgram) 5645 LOCAL_SET_GL_ERROR( 5646 GL_INVALID_OPERATION, "glUseProgram", "program not linked"); 5647 return; 5648 } 5649 service_id = program->service_id(); 5650 } 5651 if (state_.current_program.get()) { 5652 program_manager()->UnuseProgram(shader_manager(), 5653 state_.current_program.get()); 5654 } 5655 state_.current_program = program; 5656 LogClientServiceMapping("glUseProgram", program_id, service_id); 5657 glUseProgram(service_id); 5658 if (state_.current_program.get()) { 5659 program_manager()->UseProgram(state_.current_program.get()); 5660 } 5661 } 5662 5663 void GLES2DecoderImpl::RenderWarning( 5664 const char* filename, int line, const std::string& msg) { 5665 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg); 5666 } 5667 5668 void GLES2DecoderImpl::PerformanceWarning( 5669 const char* filename, int line, const std::string& msg) { 5670 logger_.LogMessage(filename, line, 5671 std::string("PERFORMANCE WARNING: ") + msg); 5672 } 5673 5674 void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture, 5675 GLuint texture_unit_index) { 5676 if (texture && texture->IsStreamTexture()) { 5677 DCHECK(stream_texture_manager()); 5678 StreamTexture* stream_tex = 5679 stream_texture_manager()->LookupStreamTexture(texture->service_id()); 5680 if (stream_tex) { 5681 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5682 stream_tex->Update(); 5683 } 5684 } 5685 } 5686 5687 void GLES2DecoderImpl::DoWillUseTexImageIfNeeded( 5688 Texture* texture, GLenum textarget) { 5689 // This might be supported in the future. 5690 if (textarget != GL_TEXTURE_2D) 5691 return; 5692 // Image is already in use if texture is attached to a framebuffer. 5693 if (texture && !texture->IsAttachedToFramebuffer()) { 5694 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 5695 if (image) { 5696 ScopedGLErrorSuppressor suppressor( 5697 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded", 5698 this); 5699 glBindTexture(textarget, texture->service_id()); 5700 image->WillUseTexImage(); 5701 RestoreCurrentTexture2DBindings(); 5702 } 5703 } 5704 } 5705 5706 void GLES2DecoderImpl::DoDidUseTexImageIfNeeded( 5707 Texture* texture, GLenum textarget) { 5708 // This might be supported in the future. 5709 if (textarget != GL_TEXTURE_2D) 5710 return; 5711 // Image is still in use if texture is attached to a framebuffer. 5712 if (texture && !texture->IsAttachedToFramebuffer()) { 5713 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 5714 if (image) { 5715 ScopedGLErrorSuppressor suppressor( 5716 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded", 5717 this); 5718 glBindTexture(textarget, texture->service_id()); 5719 image->DidUseTexImage(); 5720 RestoreCurrentTexture2DBindings(); 5721 } 5722 } 5723 } 5724 5725 bool GLES2DecoderImpl::PrepareTexturesForRender() { 5726 DCHECK(state_.current_program.get()); 5727 if (!texture_manager()->HaveUnrenderableTextures() && 5728 !texture_manager()->HaveImages() && 5729 !features().oes_egl_image_external) { 5730 return true; 5731 } 5732 5733 bool textures_set = false; 5734 const Program::SamplerIndices& sampler_indices = 5735 state_.current_program->sampler_indices(); 5736 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 5737 const Program::UniformInfo* uniform_info = 5738 state_.current_program->GetUniformInfo(sampler_indices[ii]); 5739 DCHECK(uniform_info); 5740 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 5741 GLuint texture_unit_index = uniform_info->texture_units[jj]; 5742 if (texture_unit_index < state_.texture_units.size()) { 5743 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 5744 TextureRef* texture_ref = 5745 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 5746 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type); 5747 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { 5748 textures_set = true; 5749 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5750 glBindTexture( 5751 textarget, 5752 texture_manager()->black_texture_id(uniform_info->type)); 5753 LOCAL_RENDER_WARNING( 5754 std::string("texture bound to texture unit ") + 5755 base::IntToString(texture_unit_index) + 5756 " is not renderable. It maybe non-power-of-2 and have" 5757 " incompatible texture filtering or is not" 5758 " 'texture complete'"); 5759 continue; 5760 } 5761 5762 Texture* texture = texture_ref->texture(); 5763 if (textarget == GL_TEXTURE_2D) { 5764 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 5765 if (image && !texture->IsAttachedToFramebuffer()) { 5766 ScopedGLErrorSuppressor suppressor( 5767 "GLES2DecoderImpl::PrepareTexturesForRender", this); 5768 textures_set = true; 5769 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5770 image->WillUseTexImage(); 5771 continue; 5772 } 5773 } 5774 5775 UpdateStreamTextureIfNeeded(texture, texture_unit_index); 5776 } 5777 // else: should this be an error? 5778 } 5779 } 5780 return !textures_set; 5781 } 5782 5783 void GLES2DecoderImpl::RestoreStateForTextures() { 5784 DCHECK(state_.current_program.get()); 5785 const Program::SamplerIndices& sampler_indices = 5786 state_.current_program->sampler_indices(); 5787 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 5788 const Program::UniformInfo* uniform_info = 5789 state_.current_program->GetUniformInfo(sampler_indices[ii]); 5790 DCHECK(uniform_info); 5791 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 5792 GLuint texture_unit_index = uniform_info->texture_units[jj]; 5793 if (texture_unit_index < state_.texture_units.size()) { 5794 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 5795 TextureRef* texture_ref = 5796 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 5797 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { 5798 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5799 // Get the texture_ref info that was previously bound here. 5800 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D 5801 ? texture_unit.bound_texture_2d.get() 5802 : texture_unit.bound_texture_cube_map.get(); 5803 glBindTexture(texture_unit.bind_target, 5804 texture_ref ? texture_ref->service_id() : 0); 5805 continue; 5806 } 5807 5808 Texture* texture = texture_ref->texture(); 5809 if (texture_unit.bind_target == GL_TEXTURE_2D) { 5810 gfx::GLImage* image = texture->GetLevelImage( 5811 texture_unit.bind_target, 0); 5812 if (image && !texture->IsAttachedToFramebuffer()) { 5813 ScopedGLErrorSuppressor suppressor( 5814 "GLES2DecoderImpl::RestoreStateForTextures", this); 5815 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5816 image->DidUseTexImage(); 5817 continue; 5818 } 5819 } 5820 } 5821 } 5822 } 5823 // Set the active texture back to whatever the user had it as. 5824 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 5825 } 5826 5827 bool GLES2DecoderImpl::ClearUnclearedTextures() { 5828 // Only check if there are some uncleared textures. 5829 if (!texture_manager()->HaveUnsafeTextures()) { 5830 return true; 5831 } 5832 5833 // 1: Check all textures we are about to render with. 5834 if (state_.current_program.get()) { 5835 const Program::SamplerIndices& sampler_indices = 5836 state_.current_program->sampler_indices(); 5837 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 5838 const Program::UniformInfo* uniform_info = 5839 state_.current_program->GetUniformInfo(sampler_indices[ii]); 5840 DCHECK(uniform_info); 5841 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 5842 GLuint texture_unit_index = uniform_info->texture_units[jj]; 5843 if (texture_unit_index < state_.texture_units.size()) { 5844 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 5845 TextureRef* texture_ref = 5846 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 5847 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) { 5848 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) { 5849 return false; 5850 } 5851 } 5852 } 5853 } 5854 } 5855 } 5856 return true; 5857 } 5858 5859 bool GLES2DecoderImpl::IsDrawValid( 5860 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) { 5861 // NOTE: We specifically do not check current_program->IsValid() because 5862 // it could never be invalid since glUseProgram would have failed. While 5863 // glLinkProgram could later mark the program as invalid the previous 5864 // valid program will still function if it is still the current program. 5865 if (!state_.current_program.get()) { 5866 // The program does not exist. 5867 // But GL says no ERROR. 5868 LOCAL_RENDER_WARNING("Drawing with no current shader program."); 5869 return false; 5870 } 5871 5872 return state_.vertex_attrib_manager 5873 ->ValidateBindings(function_name, 5874 this, 5875 feature_info_.get(), 5876 state_.current_program.get(), 5877 max_vertex_accessed, 5878 primcount); 5879 } 5880 5881 bool GLES2DecoderImpl::SimulateAttrib0( 5882 const char* function_name, GLuint max_vertex_accessed, bool* simulated) { 5883 DCHECK(simulated); 5884 *simulated = false; 5885 5886 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 5887 return true; 5888 5889 const VertexAttrib* attrib = 5890 state_.vertex_attrib_manager->GetVertexAttrib(0); 5891 // If it's enabled or it's not used then we don't need to do anything. 5892 bool attrib_0_used = 5893 state_.current_program->GetAttribInfoByLocation(0) != NULL; 5894 if (attrib->enabled() && attrib_0_used) { 5895 return true; 5896 } 5897 5898 // Make a buffer with a single repeated vec4 value enough to 5899 // simulate the constant value that is supposed to be here. 5900 // This is required to emulate GLES2 on GL. 5901 GLuint num_vertices = max_vertex_accessed + 1; 5902 uint32 size_needed = 0; 5903 5904 if (num_vertices == 0 || 5905 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) || 5906 size_needed > 0x7FFFFFFFU) { 5907 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 5908 return false; 5909 } 5910 5911 LOCAL_PERFORMANCE_WARNING( 5912 "Attribute 0 is disabled. This has signficant performance penalty"); 5913 5914 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 5915 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 5916 5917 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_; 5918 if (new_buffer) { 5919 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 5920 GLenum error = glGetError(); 5921 if (error != GL_NO_ERROR) { 5922 LOCAL_SET_GL_ERROR( 5923 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 5924 return false; 5925 } 5926 } 5927 5928 const Vec4& value = state_.attrib_values[0]; 5929 if (new_buffer || 5930 (attrib_0_used && 5931 (!attrib_0_buffer_matches_value_ || 5932 (value.v[0] != attrib_0_value_.v[0] || 5933 value.v[1] != attrib_0_value_.v[1] || 5934 value.v[2] != attrib_0_value_.v[2] || 5935 value.v[3] != attrib_0_value_.v[3])))) { 5936 std::vector<Vec4> temp(num_vertices, value); 5937 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); 5938 attrib_0_buffer_matches_value_ = true; 5939 attrib_0_value_ = value; 5940 attrib_0_size_ = size_needed; 5941 } 5942 5943 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); 5944 5945 if (attrib->divisor()) 5946 glVertexAttribDivisorANGLE(0, 0); 5947 5948 *simulated = true; 5949 return true; 5950 } 5951 5952 void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) { 5953 const VertexAttrib* attrib = 5954 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index); 5955 const void* ptr = reinterpret_cast<const void*>(attrib->offset()); 5956 Buffer* buffer = attrib->buffer(); 5957 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0); 5958 glVertexAttribPointer( 5959 attrib_index, attrib->size(), attrib->type(), attrib->normalized(), 5960 attrib->gl_stride(), ptr); 5961 if (attrib->divisor()) 5962 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor()); 5963 glBindBuffer( 5964 GL_ARRAY_BUFFER, 5965 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id() 5966 : 0); 5967 5968 // Never touch vertex attribute 0's state (in particular, never 5969 // disable it) when running on desktop GL because it will never be 5970 // re-enabled. 5971 if (attrib_index != 0 || 5972 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 5973 if (attrib->enabled()) { 5974 glEnableVertexAttribArray(attrib_index); 5975 } else { 5976 glDisableVertexAttribArray(attrib_index); 5977 } 5978 } 5979 } 5980 5981 bool GLES2DecoderImpl::SimulateFixedAttribs( 5982 const char* function_name, 5983 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) { 5984 DCHECK(simulated); 5985 *simulated = false; 5986 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 5987 return true; 5988 5989 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) { 5990 return true; 5991 } 5992 5993 LOCAL_PERFORMANCE_WARNING( 5994 "GL_FIXED attributes have a signficant performance penalty"); 5995 5996 // NOTE: we could be smart and try to check if a buffer is used 5997 // twice in 2 different attribs, find the overlapping parts and therefore 5998 // duplicate the minimum amount of data but this whole code path is not meant 5999 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance 6000 // tests so we just add to the buffer attrib used. 6001 6002 GLuint elements_needed = 0; 6003 const VertexAttribManager::VertexAttribList& enabled_attribs = 6004 state_.vertex_attrib_manager->GetEnabledVertexAttribs(); 6005 for (VertexAttribManager::VertexAttribList::const_iterator it = 6006 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) { 6007 const VertexAttrib* attrib = *it; 6008 const Program::VertexAttrib* attrib_info = 6009 state_.current_program->GetAttribInfoByLocation(attrib->index()); 6010 GLuint max_accessed = attrib->MaxVertexAccessed(primcount, 6011 max_vertex_accessed); 6012 GLuint num_vertices = max_accessed + 1; 6013 if (num_vertices == 0) { 6014 LOCAL_SET_GL_ERROR( 6015 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6016 return false; 6017 } 6018 if (attrib_info && 6019 attrib->CanAccess(max_accessed) && 6020 attrib->type() == GL_FIXED) { 6021 uint32 elements_used = 0; 6022 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) || 6023 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) { 6024 LOCAL_SET_GL_ERROR( 6025 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6026 return false; 6027 } 6028 } 6029 } 6030 6031 const uint32 kSizeOfFloat = sizeof(float); // NOLINT 6032 uint32 size_needed = 0; 6033 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) || 6034 size_needed > 0x7FFFFFFFU) { 6035 LOCAL_SET_GL_ERROR( 6036 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6037 return false; 6038 } 6039 6040 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 6041 6042 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); 6043 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) { 6044 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 6045 GLenum error = glGetError(); 6046 if (error != GL_NO_ERROR) { 6047 LOCAL_SET_GL_ERROR( 6048 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6049 return false; 6050 } 6051 } 6052 6053 // Copy the elements and convert to float 6054 GLintptr offset = 0; 6055 for (VertexAttribManager::VertexAttribList::const_iterator it = 6056 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) { 6057 const VertexAttrib* attrib = *it; 6058 const Program::VertexAttrib* attrib_info = 6059 state_.current_program->GetAttribInfoByLocation(attrib->index()); 6060 GLuint max_accessed = attrib->MaxVertexAccessed(primcount, 6061 max_vertex_accessed); 6062 GLuint num_vertices = max_accessed + 1; 6063 if (num_vertices == 0) { 6064 LOCAL_SET_GL_ERROR( 6065 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6066 return false; 6067 } 6068 if (attrib_info && 6069 attrib->CanAccess(max_accessed) && 6070 attrib->type() == GL_FIXED) { 6071 int num_elements = attrib->size() * kSizeOfFloat; 6072 int size = num_elements * num_vertices; 6073 scoped_ptr<float[]> data(new float[size]); 6074 const int32* src = reinterpret_cast<const int32 *>( 6075 attrib->buffer()->GetRange(attrib->offset(), size)); 6076 const int32* end = src + num_elements; 6077 float* dst = data.get(); 6078 while (src != end) { 6079 *dst++ = static_cast<float>(*src++) / 65536.0f; 6080 } 6081 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get()); 6082 glVertexAttribPointer( 6083 attrib->index(), attrib->size(), GL_FLOAT, false, 0, 6084 reinterpret_cast<GLvoid*>(offset)); 6085 offset += size; 6086 } 6087 } 6088 *simulated = true; 6089 return true; 6090 } 6091 6092 void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() { 6093 // There's no need to call glVertexAttribPointer because we shadow all the 6094 // settings and passing GL_FIXED to it will not work. 6095 glBindBuffer( 6096 GL_ARRAY_BUFFER, 6097 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id() 6098 : 0); 6099 } 6100 6101 error::Error GLES2DecoderImpl::DoDrawArrays( 6102 const char* function_name, 6103 bool instanced, 6104 GLenum mode, 6105 GLint first, 6106 GLsizei count, 6107 GLsizei primcount) { 6108 if (ShouldDeferDraws()) 6109 return error::kDeferCommandUntilLater; 6110 if (!validators_->draw_mode.IsValid(mode)) { 6111 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); 6112 return error::kNoError; 6113 } 6114 if (count < 0) { 6115 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0"); 6116 return error::kNoError; 6117 } 6118 if (primcount < 0) { 6119 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); 6120 return error::kNoError; 6121 } 6122 if (!CheckBoundFramebuffersValid(function_name)) { 6123 return error::kNoError; 6124 } 6125 // We have to check this here because the prototype for glDrawArrays 6126 // is GLint not GLsizei. 6127 if (first < 0) { 6128 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0"); 6129 return error::kNoError; 6130 } 6131 6132 if (count == 0 || (instanced && primcount == 0)) { 6133 LOCAL_RENDER_WARNING("Render count or primcount is 0."); 6134 return error::kNoError; 6135 } 6136 6137 GLuint max_vertex_accessed = first + count - 1; 6138 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { 6139 if (!ClearUnclearedTextures()) { 6140 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 6141 return error::kNoError; 6142 } 6143 bool simulated_attrib_0 = false; 6144 if (!SimulateAttrib0( 6145 function_name, max_vertex_accessed, &simulated_attrib_0)) { 6146 return error::kNoError; 6147 } 6148 bool simulated_fixed_attribs = false; 6149 if (SimulateFixedAttribs( 6150 function_name, max_vertex_accessed, &simulated_fixed_attribs, 6151 primcount)) { 6152 bool textures_set = !PrepareTexturesForRender(); 6153 ApplyDirtyState(); 6154 if (!instanced) { 6155 glDrawArrays(mode, first, count); 6156 } else { 6157 glDrawArraysInstancedANGLE(mode, first, count, primcount); 6158 } 6159 ProcessPendingQueries(); 6160 if (textures_set) { 6161 RestoreStateForTextures(); 6162 } 6163 if (simulated_fixed_attribs) { 6164 RestoreStateForSimulatedFixedAttribs(); 6165 } 6166 } 6167 if (simulated_attrib_0) { 6168 RestoreStateForAttrib(0); 6169 } 6170 } 6171 return error::kNoError; 6172 } 6173 6174 error::Error GLES2DecoderImpl::HandleDrawArrays( 6175 uint32 immediate_data_size, const cmds::DrawArrays& c) { 6176 return DoDrawArrays("glDrawArrays", 6177 false, 6178 static_cast<GLenum>(c.mode), 6179 static_cast<GLint>(c.first), 6180 static_cast<GLsizei>(c.count), 6181 0); 6182 } 6183 6184 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE( 6185 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) { 6186 if (!features().angle_instanced_arrays) { 6187 LOCAL_SET_GL_ERROR( 6188 GL_INVALID_OPERATION, 6189 "glDrawArraysInstancedANGLE", "function not available"); 6190 return error::kNoError; 6191 } 6192 return DoDrawArrays("glDrawArraysIntancedANGLE", 6193 true, 6194 static_cast<GLenum>(c.mode), 6195 static_cast<GLint>(c.first), 6196 static_cast<GLsizei>(c.count), 6197 static_cast<GLsizei>(c.primcount)); 6198 } 6199 6200 error::Error GLES2DecoderImpl::DoDrawElements( 6201 const char* function_name, 6202 bool instanced, 6203 GLenum mode, 6204 GLsizei count, 6205 GLenum type, 6206 int32 offset, 6207 GLsizei primcount) { 6208 if (ShouldDeferDraws()) 6209 return error::kDeferCommandUntilLater; 6210 if (!state_.vertex_attrib_manager->element_array_buffer()) { 6211 LOCAL_SET_GL_ERROR( 6212 GL_INVALID_OPERATION, function_name, "No element array buffer bound"); 6213 return error::kNoError; 6214 } 6215 6216 if (count < 0) { 6217 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0"); 6218 return error::kNoError; 6219 } 6220 if (offset < 0) { 6221 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0"); 6222 return error::kNoError; 6223 } 6224 if (!validators_->draw_mode.IsValid(mode)) { 6225 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); 6226 return error::kNoError; 6227 } 6228 if (!validators_->index_type.IsValid(type)) { 6229 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type"); 6230 return error::kNoError; 6231 } 6232 if (primcount < 0) { 6233 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); 6234 return error::kNoError; 6235 } 6236 6237 if (!CheckBoundFramebuffersValid(function_name)) { 6238 return error::kNoError; 6239 } 6240 6241 if (count == 0 || (instanced && primcount == 0)) { 6242 return error::kNoError; 6243 } 6244 6245 GLuint max_vertex_accessed; 6246 Buffer* element_array_buffer = 6247 state_.vertex_attrib_manager->element_array_buffer(); 6248 6249 if (!element_array_buffer->GetMaxValueForRange( 6250 offset, count, type, &max_vertex_accessed)) { 6251 LOCAL_SET_GL_ERROR( 6252 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); 6253 return error::kNoError; 6254 } 6255 6256 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { 6257 if (!ClearUnclearedTextures()) { 6258 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 6259 return error::kNoError; 6260 } 6261 bool simulated_attrib_0 = false; 6262 if (!SimulateAttrib0( 6263 function_name, max_vertex_accessed, &simulated_attrib_0)) { 6264 return error::kNoError; 6265 } 6266 bool simulated_fixed_attribs = false; 6267 if (SimulateFixedAttribs( 6268 function_name, max_vertex_accessed, &simulated_fixed_attribs, 6269 primcount)) { 6270 bool textures_set = !PrepareTexturesForRender(); 6271 ApplyDirtyState(); 6272 // TODO(gman): Refactor to hide these details in BufferManager or 6273 // VertexAttribManager. 6274 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 6275 bool used_client_side_array = false; 6276 if (element_array_buffer->IsClientSideArray()) { 6277 used_client_side_array = true; 6278 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 6279 indices = element_array_buffer->GetRange(offset, 0); 6280 } 6281 6282 if (!instanced) { 6283 glDrawElements(mode, count, type, indices); 6284 } else { 6285 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); 6286 } 6287 6288 if (used_client_side_array) { 6289 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 6290 element_array_buffer->service_id()); 6291 } 6292 6293 ProcessPendingQueries(); 6294 if (textures_set) { 6295 RestoreStateForTextures(); 6296 } 6297 if (simulated_fixed_attribs) { 6298 RestoreStateForSimulatedFixedAttribs(); 6299 } 6300 } 6301 if (simulated_attrib_0) { 6302 RestoreStateForAttrib(0); 6303 } 6304 } 6305 return error::kNoError; 6306 } 6307 6308 error::Error GLES2DecoderImpl::HandleDrawElements( 6309 uint32 immediate_data_size, const cmds::DrawElements& c) { 6310 return DoDrawElements("glDrawElements", 6311 false, 6312 static_cast<GLenum>(c.mode), 6313 static_cast<GLsizei>(c.count), 6314 static_cast<GLenum>(c.type), 6315 static_cast<int32>(c.index_offset), 6316 0); 6317 } 6318 6319 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE( 6320 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) { 6321 if (!features().angle_instanced_arrays) { 6322 LOCAL_SET_GL_ERROR( 6323 GL_INVALID_OPERATION, 6324 "glDrawElementsInstancedANGLE", "function not available"); 6325 return error::kNoError; 6326 } 6327 return DoDrawElements("glDrawElementsInstancedANGLE", 6328 true, 6329 static_cast<GLenum>(c.mode), 6330 static_cast<GLsizei>(c.count), 6331 static_cast<GLenum>(c.type), 6332 static_cast<int32>(c.index_offset), 6333 static_cast<GLsizei>(c.primcount)); 6334 } 6335 6336 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( 6337 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { 6338 GLuint max_vertex_accessed = 0; 6339 Buffer* buffer = GetBuffer(buffer_id); 6340 if (!buffer) { 6341 // TODO(gman): Should this be a GL error or a command buffer error? 6342 LOCAL_SET_GL_ERROR( 6343 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer"); 6344 } else { 6345 if (!buffer->GetMaxValueForRange( 6346 offset, count, type, &max_vertex_accessed)) { 6347 // TODO(gman): Should this be a GL error or a command buffer error? 6348 LOCAL_SET_GL_ERROR( 6349 GL_INVALID_OPERATION, 6350 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer"); 6351 } 6352 } 6353 return max_vertex_accessed; 6354 } 6355 6356 // Calls glShaderSource for the various versions of the ShaderSource command. 6357 // Assumes that data / data_size points to a piece of memory that is in range 6358 // of whatever context it came from (shared memory, immediate memory, bucket 6359 // memory.) 6360 error::Error GLES2DecoderImpl::ShaderSourceHelper( 6361 GLuint client_id, const char* data, uint32 data_size) { 6362 std::string str(data, data + data_size); 6363 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource"); 6364 if (!shader) { 6365 return error::kNoError; 6366 } 6367 // Note: We don't actually call glShaderSource here. We wait until 6368 // the call to glCompileShader. 6369 shader->UpdateSource(str.c_str()); 6370 return error::kNoError; 6371 } 6372 6373 error::Error GLES2DecoderImpl::HandleShaderSource( 6374 uint32 immediate_data_size, const cmds::ShaderSource& c) { 6375 uint32 data_size = c.data_size; 6376 const char* data = GetSharedMemoryAs<const char*>( 6377 c.data_shm_id, c.data_shm_offset, data_size); 6378 if (!data) { 6379 return error::kOutOfBounds; 6380 } 6381 return ShaderSourceHelper(c.shader, data, data_size); 6382 } 6383 6384 error::Error GLES2DecoderImpl::HandleShaderSourceImmediate( 6385 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) { 6386 uint32 data_size = c.data_size; 6387 const char* data = GetImmediateDataAs<const char*>( 6388 c, data_size, immediate_data_size); 6389 if (!data) { 6390 return error::kOutOfBounds; 6391 } 6392 return ShaderSourceHelper(c.shader, data, data_size); 6393 } 6394 6395 error::Error GLES2DecoderImpl::HandleShaderSourceBucket( 6396 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) { 6397 Bucket* bucket = GetBucket(c.data_bucket_id); 6398 if (!bucket || bucket->size() == 0) { 6399 return error::kInvalidArguments; 6400 } 6401 return ShaderSourceHelper( 6402 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1), 6403 bucket->size() - 1); 6404 } 6405 6406 void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { 6407 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader"); 6408 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader"); 6409 if (!shader) { 6410 return; 6411 } 6412 ShaderTranslator* translator = NULL; 6413 if (use_shader_translator_) { 6414 translator = shader->shader_type() == GL_VERTEX_SHADER ? 6415 vertex_translator_.get() : fragment_translator_.get(); 6416 } 6417 6418 program_manager()->DoCompileShader(shader, translator, feature_info_.get()); 6419 }; 6420 6421 void GLES2DecoderImpl::DoGetShaderiv( 6422 GLuint shader_id, GLenum pname, GLint* params) { 6423 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv"); 6424 if (!shader) { 6425 return; 6426 } 6427 switch (pname) { 6428 case GL_SHADER_SOURCE_LENGTH: 6429 *params = shader->source() ? shader->source()->size() + 1 : 0; 6430 return; 6431 case GL_COMPILE_STATUS: 6432 *params = compile_shader_always_succeeds_ ? true : shader->IsValid(); 6433 return; 6434 case GL_INFO_LOG_LENGTH: 6435 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0; 6436 return; 6437 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 6438 *params = shader->translated_source() ? 6439 shader->translated_source()->size() + 1 : 0; 6440 return; 6441 default: 6442 break; 6443 } 6444 glGetShaderiv(shader->service_id(), pname, params); 6445 } 6446 6447 error::Error GLES2DecoderImpl::HandleGetShaderSource( 6448 uint32 immediate_data_size, const cmds::GetShaderSource& c) { 6449 GLuint shader_id = c.shader; 6450 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6451 Bucket* bucket = CreateBucket(bucket_id); 6452 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource"); 6453 if (!shader || !shader->source()) { 6454 bucket->SetSize(0); 6455 return error::kNoError; 6456 } 6457 bucket->SetFromString(shader->source()->c_str()); 6458 return error::kNoError; 6459 } 6460 6461 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( 6462 uint32 immediate_data_size, 6463 const cmds::GetTranslatedShaderSourceANGLE& c) { 6464 GLuint shader_id = c.shader; 6465 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6466 Bucket* bucket = CreateBucket(bucket_id); 6467 Shader* shader = GetShaderInfoNotProgram( 6468 shader_id, "glTranslatedGetShaderSourceANGLE"); 6469 if (!shader) { 6470 bucket->SetSize(0); 6471 return error::kNoError; 6472 } 6473 6474 bucket->SetFromString(shader->translated_source() ? 6475 shader->translated_source()->c_str() : NULL); 6476 return error::kNoError; 6477 } 6478 6479 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog( 6480 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) { 6481 GLuint program_id = c.program; 6482 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6483 Bucket* bucket = CreateBucket(bucket_id); 6484 Program* program = GetProgramInfoNotShader( 6485 program_id, "glGetProgramInfoLog"); 6486 if (!program || !program->log_info()) { 6487 bucket->SetFromString(""); 6488 return error::kNoError; 6489 } 6490 bucket->SetFromString(program->log_info()->c_str()); 6491 return error::kNoError; 6492 } 6493 6494 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( 6495 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) { 6496 GLuint shader_id = c.shader; 6497 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6498 Bucket* bucket = CreateBucket(bucket_id); 6499 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog"); 6500 if (!shader || !shader->log_info()) { 6501 bucket->SetFromString(""); 6502 return error::kNoError; 6503 } 6504 bucket->SetFromString(shader->log_info()->c_str()); 6505 return error::kNoError; 6506 } 6507 6508 bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) { 6509 return state_.GetEnabled(cap); 6510 } 6511 6512 bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) { 6513 const Buffer* buffer = GetBuffer(client_id); 6514 return buffer && buffer->IsValid() && !buffer->IsDeleted(); 6515 } 6516 6517 bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) { 6518 const Framebuffer* framebuffer = 6519 GetFramebuffer(client_id); 6520 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted(); 6521 } 6522 6523 bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) { 6524 // IsProgram is true for programs as soon as they are created, until they are 6525 // deleted and no longer in use. 6526 const Program* program = GetProgram(client_id); 6527 return program != NULL && !program->IsDeleted(); 6528 } 6529 6530 bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) { 6531 const Renderbuffer* renderbuffer = 6532 GetRenderbuffer(client_id); 6533 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted(); 6534 } 6535 6536 bool GLES2DecoderImpl::DoIsShader(GLuint client_id) { 6537 // IsShader is true for shaders as soon as they are created, until they 6538 // are deleted and not attached to any programs. 6539 const Shader* shader = GetShader(client_id); 6540 return shader != NULL && !shader->IsDeleted(); 6541 } 6542 6543 bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) { 6544 const TextureRef* texture_ref = GetTexture(client_id); 6545 return texture_ref && texture_ref->texture()->IsValid(); 6546 } 6547 6548 void GLES2DecoderImpl::DoAttachShader( 6549 GLuint program_client_id, GLint shader_client_id) { 6550 Program* program = GetProgramInfoNotShader( 6551 program_client_id, "glAttachShader"); 6552 if (!program) { 6553 return; 6554 } 6555 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader"); 6556 if (!shader) { 6557 return; 6558 } 6559 if (!program->AttachShader(shader_manager(), shader)) { 6560 LOCAL_SET_GL_ERROR( 6561 GL_INVALID_OPERATION, 6562 "glAttachShader", 6563 "can not attach more than one shader of the same type."); 6564 return; 6565 } 6566 glAttachShader(program->service_id(), shader->service_id()); 6567 } 6568 6569 void GLES2DecoderImpl::DoDetachShader( 6570 GLuint program_client_id, GLint shader_client_id) { 6571 Program* program = GetProgramInfoNotShader( 6572 program_client_id, "glDetachShader"); 6573 if (!program) { 6574 return; 6575 } 6576 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader"); 6577 if (!shader) { 6578 return; 6579 } 6580 if (!program->DetachShader(shader_manager(), shader)) { 6581 LOCAL_SET_GL_ERROR( 6582 GL_INVALID_OPERATION, 6583 "glDetachShader", "shader not attached to program"); 6584 return; 6585 } 6586 glDetachShader(program->service_id(), shader->service_id()); 6587 } 6588 6589 void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) { 6590 Program* program = GetProgramInfoNotShader( 6591 program_client_id, "glValidateProgram"); 6592 if (!program) { 6593 return; 6594 } 6595 program->Validate(); 6596 } 6597 6598 void GLES2DecoderImpl::GetVertexAttribHelper( 6599 const VertexAttrib* attrib, GLenum pname, GLint* params) { 6600 switch (pname) { 6601 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { 6602 Buffer* buffer = attrib->buffer(); 6603 if (buffer && !buffer->IsDeleted()) { 6604 GLuint client_id; 6605 buffer_manager()->GetClientId(buffer->service_id(), &client_id); 6606 *params = client_id; 6607 } 6608 break; 6609 } 6610 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 6611 *params = attrib->enabled(); 6612 break; 6613 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 6614 *params = attrib->size(); 6615 break; 6616 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 6617 *params = attrib->gl_stride(); 6618 break; 6619 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 6620 *params = attrib->type(); 6621 break; 6622 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 6623 *params = attrib->normalized(); 6624 break; 6625 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 6626 *params = attrib->divisor(); 6627 break; 6628 default: 6629 NOTREACHED(); 6630 break; 6631 } 6632 } 6633 6634 void GLES2DecoderImpl::DoGetVertexAttribfv( 6635 GLuint index, GLenum pname, GLfloat* params) { 6636 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); 6637 if (!attrib) { 6638 LOCAL_SET_GL_ERROR( 6639 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range"); 6640 return; 6641 } 6642 switch (pname) { 6643 case GL_CURRENT_VERTEX_ATTRIB: { 6644 const Vec4& value = state_.attrib_values[index]; 6645 params[0] = value.v[0]; 6646 params[1] = value.v[1]; 6647 params[2] = value.v[2]; 6648 params[3] = value.v[3]; 6649 break; 6650 } 6651 default: { 6652 GLint value = 0; 6653 GetVertexAttribHelper(attrib, pname, &value); 6654 *params = static_cast<GLfloat>(value); 6655 break; 6656 } 6657 } 6658 } 6659 6660 void GLES2DecoderImpl::DoGetVertexAttribiv( 6661 GLuint index, GLenum pname, GLint* params) { 6662 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); 6663 if (!attrib) { 6664 LOCAL_SET_GL_ERROR( 6665 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range"); 6666 return; 6667 } 6668 switch (pname) { 6669 case GL_CURRENT_VERTEX_ATTRIB: { 6670 const Vec4& value = state_.attrib_values[index]; 6671 params[0] = static_cast<GLint>(value.v[0]); 6672 params[1] = static_cast<GLint>(value.v[1]); 6673 params[2] = static_cast<GLint>(value.v[2]); 6674 params[3] = static_cast<GLint>(value.v[3]); 6675 break; 6676 } 6677 default: 6678 GetVertexAttribHelper(attrib, pname, params); 6679 break; 6680 } 6681 } 6682 6683 bool GLES2DecoderImpl::SetVertexAttribValue( 6684 const char* function_name, GLuint index, const GLfloat* value) { 6685 if (index >= state_.attrib_values.size()) { 6686 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range"); 6687 return false; 6688 } 6689 Vec4& v = state_.attrib_values[index]; 6690 v.v[0] = value[0]; 6691 v.v[1] = value[1]; 6692 v.v[2] = value[2]; 6693 v.v[3] = value[3]; 6694 return true; 6695 } 6696 6697 void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) { 6698 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, }; 6699 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) { 6700 glVertexAttrib1f(index, v0); 6701 } 6702 } 6703 6704 void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) { 6705 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, }; 6706 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) { 6707 glVertexAttrib2f(index, v0, v1); 6708 } 6709 } 6710 6711 void GLES2DecoderImpl::DoVertexAttrib3f( 6712 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) { 6713 GLfloat v[4] = { v0, v1, v2, 1.0f, }; 6714 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) { 6715 glVertexAttrib3f(index, v0, v1, v2); 6716 } 6717 } 6718 6719 void GLES2DecoderImpl::DoVertexAttrib4f( 6720 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { 6721 GLfloat v[4] = { v0, v1, v2, v3, }; 6722 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) { 6723 glVertexAttrib4f(index, v0, v1, v2, v3); 6724 } 6725 } 6726 6727 void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) { 6728 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, }; 6729 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) { 6730 glVertexAttrib1fv(index, v); 6731 } 6732 } 6733 6734 void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) { 6735 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, }; 6736 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) { 6737 glVertexAttrib2fv(index, v); 6738 } 6739 } 6740 6741 void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) { 6742 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, }; 6743 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) { 6744 glVertexAttrib3fv(index, v); 6745 } 6746 } 6747 6748 void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) { 6749 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) { 6750 glVertexAttrib4fv(index, v); 6751 } 6752 } 6753 6754 error::Error GLES2DecoderImpl::HandleVertexAttribPointer( 6755 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) { 6756 6757 if (!state_.bound_array_buffer.get() || 6758 state_.bound_array_buffer->IsDeleted()) { 6759 if (state_.vertex_attrib_manager.get() == 6760 default_vertex_attrib_manager_.get()) { 6761 LOCAL_SET_GL_ERROR( 6762 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound"); 6763 return error::kNoError; 6764 } else if (c.offset != 0) { 6765 LOCAL_SET_GL_ERROR( 6766 GL_INVALID_VALUE, 6767 "glVertexAttribPointer", "client side arrays are not allowed"); 6768 return error::kNoError; 6769 } 6770 } 6771 6772 GLuint indx = c.indx; 6773 GLint size = c.size; 6774 GLenum type = c.type; 6775 GLboolean normalized = c.normalized; 6776 GLsizei stride = c.stride; 6777 GLsizei offset = c.offset; 6778 const void* ptr = reinterpret_cast<const void*>(offset); 6779 if (!validators_->vertex_attrib_type.IsValid(type)) { 6780 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type"); 6781 return error::kNoError; 6782 } 6783 if (!validators_->vertex_attrib_size.IsValid(size)) { 6784 LOCAL_SET_GL_ERROR( 6785 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE"); 6786 return error::kNoError; 6787 } 6788 if (indx >= group_->max_vertex_attribs()) { 6789 LOCAL_SET_GL_ERROR( 6790 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range"); 6791 return error::kNoError; 6792 } 6793 if (stride < 0) { 6794 LOCAL_SET_GL_ERROR( 6795 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0"); 6796 return error::kNoError; 6797 } 6798 if (stride > 255) { 6799 LOCAL_SET_GL_ERROR( 6800 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255"); 6801 return error::kNoError; 6802 } 6803 if (offset < 0) { 6804 LOCAL_SET_GL_ERROR( 6805 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0"); 6806 return error::kNoError; 6807 } 6808 GLsizei component_size = 6809 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); 6810 if (offset % component_size > 0) { 6811 LOCAL_SET_GL_ERROR( 6812 GL_INVALID_OPERATION, 6813 "glVertexAttribPointer", "offset not valid for type"); 6814 return error::kNoError; 6815 } 6816 if (stride % component_size > 0) { 6817 LOCAL_SET_GL_ERROR( 6818 GL_INVALID_OPERATION, 6819 "glVertexAttribPointer", "stride not valid for type"); 6820 return error::kNoError; 6821 } 6822 state_.vertex_attrib_manager 6823 ->SetAttribInfo(indx, 6824 state_.bound_array_buffer.get(), 6825 size, 6826 type, 6827 normalized, 6828 stride, 6829 stride != 0 ? stride : component_size * size, 6830 offset); 6831 if (type != GL_FIXED) { 6832 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); 6833 } 6834 return error::kNoError; 6835 } 6836 6837 void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width, 6838 GLsizei height) { 6839 state_.viewport_x = x; 6840 state_.viewport_y = y; 6841 state_.viewport_width = std::min(width, viewport_max_width_); 6842 state_.viewport_height = std::min(height, viewport_max_height_); 6843 glViewport(x, y, width, height); 6844 } 6845 6846 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( 6847 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) { 6848 if (!features().angle_instanced_arrays) { 6849 LOCAL_SET_GL_ERROR( 6850 GL_INVALID_OPERATION, 6851 "glVertexAttribDivisorANGLE", "function not available"); 6852 } 6853 GLuint index = c.index; 6854 GLuint divisor = c.divisor; 6855 if (index >= group_->max_vertex_attribs()) { 6856 LOCAL_SET_GL_ERROR( 6857 GL_INVALID_VALUE, 6858 "glVertexAttribDivisorANGLE", "index out of range"); 6859 return error::kNoError; 6860 } 6861 6862 state_.vertex_attrib_manager->SetDivisor( 6863 index, 6864 divisor); 6865 glVertexAttribDivisorANGLE(index, divisor); 6866 return error::kNoError; 6867 } 6868 6869 void GLES2DecoderImpl::FinishReadPixels( 6870 const cmds::ReadPixels& c, 6871 GLuint buffer) { 6872 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels"); 6873 GLsizei width = c.width; 6874 GLsizei height = c.height; 6875 GLenum format = c.format; 6876 GLenum type = c.type; 6877 typedef cmds::ReadPixels::Result Result; 6878 uint32 pixels_size; 6879 Result* result = NULL; 6880 if (c.result_shm_id != 0) { 6881 result = GetSharedMemoryAs<Result*>( 6882 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 6883 if (!result) { 6884 if (buffer != 0) { 6885 glDeleteBuffersARB(1, &buffer); 6886 } 6887 return; 6888 } 6889 } 6890 GLES2Util::ComputeImageDataSizes( 6891 width, height, format, type, state_.pack_alignment, &pixels_size, 6892 NULL, NULL); 6893 void* pixels = GetSharedMemoryAs<void*>( 6894 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 6895 if (!pixels) { 6896 if (buffer != 0) { 6897 glDeleteBuffersARB(1, &buffer); 6898 } 6899 return; 6900 } 6901 6902 if (buffer != 0) { 6903 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); 6904 void* data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); 6905 memcpy(pixels, data, pixels_size); 6906 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't 6907 // have to restore the state. 6908 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); 6909 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 6910 glDeleteBuffersARB(1, &buffer); 6911 } 6912 6913 if (result != NULL) { 6914 *result = true; 6915 } 6916 6917 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 6918 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 6919 if ((channels_exist & 0x0008) == 0 && 6920 workarounds().clear_alpha_in_readpixels) { 6921 // Set the alpha to 255 because some drivers are buggy in this regard. 6922 uint32 temp_size; 6923 6924 uint32 unpadded_row_size; 6925 uint32 padded_row_size; 6926 if (!GLES2Util::ComputeImageDataSizes( 6927 width, 2, format, type, state_.pack_alignment, &temp_size, 6928 &unpadded_row_size, &padded_row_size)) { 6929 return; 6930 } 6931 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time 6932 // of this implementation. 6933 if (type != GL_UNSIGNED_BYTE) { 6934 return; 6935 } 6936 switch (format) { 6937 case GL_RGBA: 6938 case GL_BGRA_EXT: 6939 case GL_ALPHA: { 6940 int offset = (format == GL_ALPHA) ? 0 : 3; 6941 int step = (format == GL_ALPHA) ? 1 : 4; 6942 uint8* dst = static_cast<uint8*>(pixels) + offset; 6943 for (GLint yy = 0; yy < height; ++yy) { 6944 uint8* end = dst + unpadded_row_size; 6945 for (uint8* d = dst; d < end; d += step) { 6946 *d = 255; 6947 } 6948 dst += padded_row_size; 6949 } 6950 break; 6951 } 6952 default: 6953 break; 6954 } 6955 } 6956 } 6957 6958 6959 error::Error GLES2DecoderImpl::HandleReadPixels( 6960 uint32 immediate_data_size, const cmds::ReadPixels& c) { 6961 if (ShouldDeferReads()) 6962 return error::kDeferCommandUntilLater; 6963 GLint x = c.x; 6964 GLint y = c.y; 6965 GLsizei width = c.width; 6966 GLsizei height = c.height; 6967 GLenum format = c.format; 6968 GLenum type = c.type; 6969 GLboolean async = c.async; 6970 if (width < 0 || height < 0) { 6971 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); 6972 return error::kNoError; 6973 } 6974 typedef cmds::ReadPixels::Result Result; 6975 uint32 pixels_size; 6976 if (!GLES2Util::ComputeImageDataSizes( 6977 width, height, format, type, state_.pack_alignment, &pixels_size, 6978 NULL, NULL)) { 6979 return error::kOutOfBounds; 6980 } 6981 void* pixels = GetSharedMemoryAs<void*>( 6982 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 6983 if (!pixels) { 6984 return error::kOutOfBounds; 6985 } 6986 Result* result = NULL; 6987 if (c.result_shm_id != 0) { 6988 result = GetSharedMemoryAs<Result*>( 6989 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 6990 if (!result) { 6991 return error::kOutOfBounds; 6992 } 6993 } 6994 6995 if (!validators_->read_pixel_format.IsValid(format)) { 6996 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format"); 6997 return error::kNoError; 6998 } 6999 if (!validators_->pixel_type.IsValid(type)) { 7000 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type"); 7001 return error::kNoError; 7002 } 7003 if (width == 0 || height == 0) { 7004 return error::kNoError; 7005 } 7006 7007 // Get the size of the current fbo or backbuffer. 7008 gfx::Size max_size = GetBoundReadFrameBufferSize(); 7009 7010 int32 max_x; 7011 int32 max_y; 7012 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) { 7013 LOCAL_SET_GL_ERROR( 7014 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7015 return error::kNoError; 7016 } 7017 7018 if (!CheckBoundFramebuffersValid("glReadPixels")) { 7019 return error::kNoError; 7020 } 7021 7022 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel"); 7023 7024 ScopedResolvedFrameBufferBinder binder(this, false, true); 7025 7026 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) { 7027 // The user requested an out of range area. Get the results 1 line 7028 // at a time. 7029 uint32 temp_size; 7030 uint32 unpadded_row_size; 7031 uint32 padded_row_size; 7032 if (!GLES2Util::ComputeImageDataSizes( 7033 width, 2, format, type, state_.pack_alignment, &temp_size, 7034 &unpadded_row_size, &padded_row_size)) { 7035 LOCAL_SET_GL_ERROR( 7036 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7037 return error::kNoError; 7038 } 7039 7040 GLint dest_x_offset = std::max(-x, 0); 7041 uint32 dest_row_offset; 7042 if (!GLES2Util::ComputeImageDataSizes( 7043 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset, 7044 NULL, NULL)) { 7045 LOCAL_SET_GL_ERROR( 7046 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7047 return error::kNoError; 7048 } 7049 7050 // Copy each row into the larger dest rect. 7051 int8* dst = static_cast<int8*>(pixels); 7052 GLint read_x = std::max(0, x); 7053 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x)); 7054 GLint read_width = read_end_x - read_x; 7055 for (GLint yy = 0; yy < height; ++yy) { 7056 GLint ry = y + yy; 7057 7058 // Clear the row. 7059 memset(dst, 0, unpadded_row_size); 7060 7061 // If the row is in range, copy it. 7062 if (ry >= 0 && ry < max_size.height() && read_width > 0) { 7063 glReadPixels( 7064 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); 7065 } 7066 dst += padded_row_size; 7067 } 7068 } else { 7069 if (async && features().use_async_readpixels) { 7070 GLuint buffer; 7071 glGenBuffersARB(1, &buffer); 7072 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); 7073 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); 7074 GLenum error = glGetError(); 7075 if (error == GL_NO_ERROR) { 7076 glReadPixels(x, y, width, height, format, type, 0); 7077 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( 7078 new FenceCallback())); 7079 WaitForReadPixels(base::Bind( 7080 &GLES2DecoderImpl::FinishReadPixels, 7081 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr 7082 <GLES2DecoderImpl>(this), 7083 c, buffer)); 7084 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7085 return error::kNoError; 7086 } 7087 } 7088 glReadPixels(x, y, width, height, format, type, pixels); 7089 } 7090 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); 7091 if (error == GL_NO_ERROR) { 7092 if (result != NULL) { 7093 *result = true; 7094 } 7095 FinishReadPixels(c, 0); 7096 } 7097 7098 return error::kNoError; 7099 } 7100 7101 error::Error GLES2DecoderImpl::HandlePixelStorei( 7102 uint32 immediate_data_size, const cmds::PixelStorei& c) { 7103 GLenum pname = c.pname; 7104 GLenum param = c.param; 7105 if (!validators_->pixel_store.IsValid(pname)) { 7106 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); 7107 return error::kNoError; 7108 } 7109 switch (pname) { 7110 case GL_PACK_ALIGNMENT: 7111 case GL_UNPACK_ALIGNMENT: 7112 if (!validators_->pixel_store_alignment.IsValid(param)) { 7113 LOCAL_SET_GL_ERROR( 7114 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE"); 7115 return error::kNoError; 7116 } 7117 break; 7118 case GL_UNPACK_FLIP_Y_CHROMIUM: 7119 unpack_flip_y_ = (param != 0); 7120 return error::kNoError; 7121 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 7122 unpack_premultiply_alpha_ = (param != 0); 7123 return error::kNoError; 7124 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 7125 unpack_unpremultiply_alpha_ = (param != 0); 7126 return error::kNoError; 7127 default: 7128 break; 7129 } 7130 glPixelStorei(pname, param); 7131 switch (pname) { 7132 case GL_PACK_ALIGNMENT: 7133 state_.pack_alignment = param; 7134 break; 7135 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 7136 state_.pack_reverse_row_order = (param != 0); 7137 break; 7138 case GL_UNPACK_ALIGNMENT: 7139 state_.unpack_alignment = param; 7140 break; 7141 default: 7142 // Validation should have prevented us from getting here. 7143 NOTREACHED(); 7144 break; 7145 } 7146 return error::kNoError; 7147 } 7148 7149 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( 7150 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) { 7151 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); 7152 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) { 7153 LOCAL_SET_GL_ERROR( 7154 GL_INVALID_OPERATION, 7155 "glPostSubBufferCHROMIUM", "command not supported by surface"); 7156 return error::kNoError; 7157 } 7158 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) { 7159 return error::kNoError; 7160 } else { 7161 LOG(ERROR) << "Context lost because PostSubBuffer failed."; 7162 return error::kLostContext; 7163 } 7164 } 7165 7166 error::Error GLES2DecoderImpl::GetAttribLocationHelper( 7167 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 7168 const std::string& name_str) { 7169 if (!StringIsValidForGLES(name_str.c_str())) { 7170 LOCAL_SET_GL_ERROR( 7171 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); 7172 return error::kNoError; 7173 } 7174 Program* program = GetProgramInfoNotShader( 7175 client_id, "glGetAttribLocation"); 7176 if (!program) { 7177 return error::kNoError; 7178 } 7179 if (!program->IsValid()) { 7180 LOCAL_SET_GL_ERROR( 7181 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked"); 7182 return error::kNoError; 7183 } 7184 GLint* location = GetSharedMemoryAs<GLint*>( 7185 location_shm_id, location_shm_offset, sizeof(GLint)); 7186 if (!location) { 7187 return error::kOutOfBounds; 7188 } 7189 // Require the client to init this incase the context is lost and we are no 7190 // longer executing commands. 7191 if (*location != -1) { 7192 return error::kGenericError; 7193 } 7194 *location = program->GetAttribLocation(name_str); 7195 return error::kNoError; 7196 } 7197 7198 error::Error GLES2DecoderImpl::HandleGetAttribLocation( 7199 uint32 immediate_data_size, const cmds::GetAttribLocation& c) { 7200 uint32 name_size = c.data_size; 7201 const char* name = GetSharedMemoryAs<const char*>( 7202 c.name_shm_id, c.name_shm_offset, name_size); 7203 if (!name) { 7204 return error::kOutOfBounds; 7205 } 7206 String name_str(name, name_size); 7207 return GetAttribLocationHelper( 7208 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7209 } 7210 7211 error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate( 7212 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) { 7213 uint32 name_size = c.data_size; 7214 const char* name = GetImmediateDataAs<const char*>( 7215 c, name_size, immediate_data_size); 7216 if (!name) { 7217 return error::kOutOfBounds; 7218 } 7219 String name_str(name, name_size); 7220 return GetAttribLocationHelper( 7221 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7222 } 7223 7224 error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket( 7225 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) { 7226 Bucket* bucket = GetBucket(c.name_bucket_id); 7227 if (!bucket) { 7228 return error::kInvalidArguments; 7229 } 7230 std::string name_str; 7231 if (!bucket->GetAsString(&name_str)) { 7232 return error::kInvalidArguments; 7233 } 7234 return GetAttribLocationHelper( 7235 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7236 } 7237 7238 error::Error GLES2DecoderImpl::GetUniformLocationHelper( 7239 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 7240 const std::string& name_str) { 7241 if (!StringIsValidForGLES(name_str.c_str())) { 7242 LOCAL_SET_GL_ERROR( 7243 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); 7244 return error::kNoError; 7245 } 7246 Program* program = GetProgramInfoNotShader( 7247 client_id, "glUniformLocation"); 7248 if (!program) { 7249 return error::kNoError; 7250 } 7251 if (!program->IsValid()) { 7252 LOCAL_SET_GL_ERROR( 7253 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked"); 7254 return error::kNoError; 7255 } 7256 GLint* location = GetSharedMemoryAs<GLint*>( 7257 location_shm_id, location_shm_offset, sizeof(GLint)); 7258 if (!location) { 7259 return error::kOutOfBounds; 7260 } 7261 // Require the client to init this incase the context is lost an we are no 7262 // longer executing commands. 7263 if (*location != -1) { 7264 return error::kGenericError; 7265 } 7266 *location = program->GetUniformFakeLocation(name_str); 7267 return error::kNoError; 7268 } 7269 7270 error::Error GLES2DecoderImpl::HandleGetUniformLocation( 7271 uint32 immediate_data_size, const cmds::GetUniformLocation& c) { 7272 uint32 name_size = c.data_size; 7273 const char* name = GetSharedMemoryAs<const char*>( 7274 c.name_shm_id, c.name_shm_offset, name_size); 7275 if (!name) { 7276 return error::kOutOfBounds; 7277 } 7278 String name_str(name, name_size); 7279 return GetUniformLocationHelper( 7280 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7281 } 7282 7283 error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate( 7284 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) { 7285 uint32 name_size = c.data_size; 7286 const char* name = GetImmediateDataAs<const char*>( 7287 c, name_size, immediate_data_size); 7288 if (!name) { 7289 return error::kOutOfBounds; 7290 } 7291 String name_str(name, name_size); 7292 return GetUniformLocationHelper( 7293 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7294 } 7295 7296 error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket( 7297 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) { 7298 Bucket* bucket = GetBucket(c.name_bucket_id); 7299 if (!bucket) { 7300 return error::kInvalidArguments; 7301 } 7302 std::string name_str; 7303 if (!bucket->GetAsString(&name_str)) { 7304 return error::kInvalidArguments; 7305 } 7306 return GetUniformLocationHelper( 7307 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7308 } 7309 7310 error::Error GLES2DecoderImpl::HandleGetString( 7311 uint32 immediate_data_size, const cmds::GetString& c) { 7312 GLenum name = static_cast<GLenum>(c.name); 7313 if (!validators_->string_type.IsValid(name)) { 7314 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name"); 7315 return error::kNoError; 7316 } 7317 const char* gl_str = reinterpret_cast<const char*>(glGetString(name)); 7318 const char* str = NULL; 7319 std::string extensions; 7320 switch (name) { 7321 case GL_VERSION: 7322 str = "OpenGL ES 2.0 Chromium"; 7323 break; 7324 case GL_SHADING_LANGUAGE_VERSION: 7325 str = "OpenGL ES GLSL ES 1.0 Chromium"; 7326 break; 7327 case GL_RENDERER: 7328 str = "Chromium"; 7329 break; 7330 case GL_VENDOR: 7331 str = "Chromium"; 7332 break; 7333 case GL_EXTENSIONS: 7334 { 7335 // For WebGL contexts, strip out the OES derivatives and 7336 // EXT frag depth extensions if they have not been enabled. 7337 if (force_webgl_glsl_validation_) { 7338 extensions = feature_info_->extensions(); 7339 if (!derivatives_explicitly_enabled_) { 7340 size_t offset = extensions.find(kOESDerivativeExtension); 7341 if (std::string::npos != offset) { 7342 extensions.replace(offset, arraysize(kOESDerivativeExtension), 7343 std::string()); 7344 } 7345 } 7346 if (!frag_depth_explicitly_enabled_) { 7347 size_t offset = extensions.find(kEXTFragDepthExtension); 7348 if (std::string::npos != offset) { 7349 extensions.replace(offset, arraysize(kEXTFragDepthExtension), 7350 std::string()); 7351 } 7352 } 7353 if (!draw_buffers_explicitly_enabled_) { 7354 size_t offset = extensions.find(kEXTDrawBuffersExtension); 7355 if (std::string::npos != offset) { 7356 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension), 7357 std::string()); 7358 } 7359 } 7360 } else { 7361 extensions = feature_info_->extensions().c_str(); 7362 } 7363 std::string surface_extensions = surface_->GetExtensions(); 7364 if (!surface_extensions.empty()) 7365 extensions += " " + surface_extensions; 7366 str = extensions.c_str(); 7367 } 7368 break; 7369 default: 7370 str = gl_str; 7371 break; 7372 } 7373 Bucket* bucket = CreateBucket(c.bucket_id); 7374 bucket->SetFromString(str); 7375 return error::kNoError; 7376 } 7377 7378 error::Error GLES2DecoderImpl::HandleBufferData( 7379 uint32 immediate_data_size, const cmds::BufferData& c) { 7380 GLenum target = static_cast<GLenum>(c.target); 7381 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 7382 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 7383 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 7384 GLenum usage = static_cast<GLenum>(c.usage); 7385 const void* data = NULL; 7386 if (data_shm_id != 0 || data_shm_offset != 0) { 7387 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); 7388 if (!data) { 7389 return error::kOutOfBounds; 7390 } 7391 } 7392 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage); 7393 return error::kNoError; 7394 } 7395 7396 error::Error GLES2DecoderImpl::HandleBufferDataImmediate( 7397 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) { 7398 GLenum target = static_cast<GLenum>(c.target); 7399 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 7400 const void* data = GetImmediateDataAs<const void*>( 7401 c, size, immediate_data_size); 7402 if (!data) { 7403 return error::kOutOfBounds; 7404 } 7405 GLenum usage = static_cast<GLenum>(c.usage); 7406 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage); 7407 return error::kNoError; 7408 } 7409 7410 void GLES2DecoderImpl::DoBufferSubData( 7411 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { 7412 // Just delegate it. Some validation is actually done before this. 7413 buffer_manager()->ValidateAndDoBufferSubData( 7414 &state_, target, offset, size, data); 7415 } 7416 7417 bool GLES2DecoderImpl::ClearLevel( 7418 unsigned service_id, 7419 unsigned bind_target, 7420 unsigned target, 7421 int level, 7422 unsigned format, 7423 unsigned type, 7424 int width, 7425 int height, 7426 bool is_texture_immutable) { 7427 uint32 channels = GLES2Util::GetChannelsForFormat(format); 7428 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) { 7429 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D 7430 // on depth formats. 7431 GLuint fb = 0; 7432 glGenFramebuffersEXT(1, &fb); 7433 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); 7434 7435 bool have_stencil = (channels & GLES2Util::kStencil) != 0; 7436 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : 7437 GL_DEPTH_ATTACHMENT; 7438 7439 glFramebufferTexture2DEXT( 7440 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); 7441 // ANGLE promises a depth only attachment ok. 7442 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != 7443 GL_FRAMEBUFFER_COMPLETE) { 7444 return false; 7445 } 7446 glClearStencil(0); 7447 glStencilMask(-1); 7448 glClearDepth(1.0f); 7449 glDepthMask(true); 7450 glDisable(GL_SCISSOR_TEST); 7451 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0)); 7452 7453 RestoreClearState(); 7454 7455 glDeleteFramebuffersEXT(1, &fb); 7456 Framebuffer* framebuffer = 7457 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 7458 GLuint fb_service_id = 7459 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); 7460 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id); 7461 return true; 7462 } 7463 7464 static const uint32 kMaxZeroSize = 1024 * 1024 * 4; 7465 7466 uint32 size; 7467 uint32 padded_row_size; 7468 if (!GLES2Util::ComputeImageDataSizes( 7469 width, height, format, type, state_.unpack_alignment, &size, 7470 NULL, &padded_row_size)) { 7471 return false; 7472 } 7473 7474 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size); 7475 7476 int tile_height; 7477 7478 if (size > kMaxZeroSize) { 7479 if (kMaxZeroSize < padded_row_size) { 7480 // That'd be an awfully large texture. 7481 return false; 7482 } 7483 // We should never have a large total size with a zero row size. 7484 DCHECK_GT(padded_row_size, 0U); 7485 tile_height = kMaxZeroSize / padded_row_size; 7486 if (!GLES2Util::ComputeImageDataSizes( 7487 width, tile_height, format, type, state_.unpack_alignment, &size, 7488 NULL, NULL)) { 7489 return false; 7490 } 7491 } else { 7492 tile_height = height; 7493 } 7494 7495 // Assumes the size has already been checked. 7496 scoped_ptr<char[]> zero(new char[size]); 7497 memset(zero.get(), 0, size); 7498 glBindTexture(bind_target, service_id); 7499 7500 GLint y = 0; 7501 while (y < height) { 7502 GLint h = y + tile_height > height ? height - y : tile_height; 7503 if (is_texture_immutable || h != height) { 7504 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); 7505 } else { 7506 glTexImage2D( 7507 target, level, format, width, h, 0, format, type, zero.get()); 7508 } 7509 y += tile_height; 7510 } 7511 TextureRef* texture = GetTextureInfoForTarget(bind_target); 7512 glBindTexture(bind_target, texture ? texture->service_id() : 0); 7513 return true; 7514 } 7515 7516 namespace { 7517 7518 const int kS3TCBlockWidth = 4; 7519 const int kS3TCBlockHeight = 4; 7520 const int kS3TCDXT1BlockSize = 8; 7521 const int kS3TCDXT3AndDXT5BlockSize = 16; 7522 const int kETC1BlockWidth = 4; 7523 const int kETC1BlockHeight = 4; 7524 const int kETC1BlockSize = 8; 7525 7526 bool IsValidDXTSize(GLint level, GLsizei size) { 7527 return (size == 1) || 7528 (size == 2) || !(size % kS3TCBlockWidth); 7529 } 7530 7531 } // anonymous namespace. 7532 7533 bool GLES2DecoderImpl::ValidateCompressedTexFuncData( 7534 const char* function_name, 7535 GLsizei width, GLsizei height, GLenum format, size_t size) { 7536 unsigned int bytes_required = 0; 7537 7538 switch (format) { 7539 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 7540 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { 7541 int num_blocks_across = 7542 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; 7543 int num_blocks_down = 7544 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; 7545 int num_blocks = num_blocks_across * num_blocks_down; 7546 bytes_required = num_blocks * kS3TCDXT1BlockSize; 7547 break; 7548 } 7549 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 7550 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 7551 int num_blocks_across = 7552 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; 7553 int num_blocks_down = 7554 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; 7555 int num_blocks = num_blocks_across * num_blocks_down; 7556 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; 7557 break; 7558 } 7559 case GL_ETC1_RGB8_OES: { 7560 int num_blocks_across = 7561 (width + kETC1BlockWidth - 1) / kETC1BlockWidth; 7562 int num_blocks_down = 7563 (height + kETC1BlockHeight - 1) / kETC1BlockHeight; 7564 int num_blocks = num_blocks_across * num_blocks_down; 7565 bytes_required = num_blocks * kETC1BlockSize; 7566 break; 7567 } 7568 default: 7569 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); 7570 return false; 7571 } 7572 7573 if (size != bytes_required) { 7574 LOCAL_SET_GL_ERROR( 7575 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); 7576 return false; 7577 } 7578 7579 return true; 7580 } 7581 7582 bool GLES2DecoderImpl::ValidateCompressedTexDimensions( 7583 const char* function_name, 7584 GLint level, GLsizei width, GLsizei height, GLenum format) { 7585 switch (format) { 7586 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 7587 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 7588 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 7589 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 7590 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { 7591 LOCAL_SET_GL_ERROR( 7592 GL_INVALID_OPERATION, function_name, 7593 "width or height invalid for level"); 7594 return false; 7595 } 7596 return true; 7597 } 7598 case GL_ETC1_RGB8_OES: 7599 if (width <= 0 || height <= 0) { 7600 LOCAL_SET_GL_ERROR( 7601 GL_INVALID_OPERATION, function_name, 7602 "width or height invalid for level"); 7603 return false; 7604 } 7605 return true; 7606 default: 7607 return false; 7608 } 7609 } 7610 7611 bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( 7612 const char* function_name, 7613 GLenum target, GLint level, GLint xoffset, GLint yoffset, 7614 GLsizei width, GLsizei height, GLenum format, 7615 Texture* texture) { 7616 if (xoffset < 0 || yoffset < 0) { 7617 LOCAL_SET_GL_ERROR( 7618 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0"); 7619 return false; 7620 } 7621 7622 switch (format) { 7623 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 7624 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 7625 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 7626 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 7627 const int kBlockWidth = 4; 7628 const int kBlockHeight = 4; 7629 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { 7630 LOCAL_SET_GL_ERROR( 7631 GL_INVALID_OPERATION, function_name, 7632 "xoffset or yoffset not multiple of 4"); 7633 return false; 7634 } 7635 GLsizei tex_width = 0; 7636 GLsizei tex_height = 0; 7637 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || 7638 width - xoffset > tex_width || 7639 height - yoffset > tex_height) { 7640 LOCAL_SET_GL_ERROR( 7641 GL_INVALID_OPERATION, function_name, "dimensions out of range"); 7642 return false; 7643 } 7644 return ValidateCompressedTexDimensions( 7645 function_name, level, width, height, format); 7646 } 7647 case GL_ETC1_RGB8_OES: { 7648 LOCAL_SET_GL_ERROR( 7649 GL_INVALID_OPERATION, function_name, 7650 "TexsubImage2d not supported for ECT1_RGB8_OES textures"); 7651 return false; 7652 } 7653 default: 7654 return false; 7655 } 7656 } 7657 7658 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( 7659 GLenum target, 7660 GLint level, 7661 GLenum internal_format, 7662 GLsizei width, 7663 GLsizei height, 7664 GLint border, 7665 GLsizei image_size, 7666 const void* data) { 7667 // TODO(gman): Validate image_size is correct for width, height and format. 7668 if (!validators_->texture_target.IsValid(target)) { 7669 LOCAL_SET_GL_ERROR_INVALID_ENUM( 7670 "glCompressedTexImage2D", target, "target"); 7671 return error::kNoError; 7672 } 7673 if (!validators_->compressed_texture_format.IsValid( 7674 internal_format)) { 7675 LOCAL_SET_GL_ERROR_INVALID_ENUM( 7676 "glCompressedTexImage2D", internal_format, "internal_format"); 7677 return error::kNoError; 7678 } 7679 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 7680 border != 0) { 7681 LOCAL_SET_GL_ERROR( 7682 GL_INVALID_VALUE, 7683 "glCompressedTexImage2D", "dimensions out of range"); 7684 return error::kNoError; 7685 } 7686 TextureRef* texture_ref = GetTextureInfoForTarget(target); 7687 if (!texture_ref) { 7688 LOCAL_SET_GL_ERROR( 7689 GL_INVALID_VALUE, 7690 "glCompressedTexImage2D", "unknown texture target"); 7691 return error::kNoError; 7692 } 7693 Texture* texture = texture_ref->texture(); 7694 if (texture->IsImmutable()) { 7695 LOCAL_SET_GL_ERROR( 7696 GL_INVALID_OPERATION, 7697 "glCompressedTexImage2D", "texture is immutable"); 7698 return error::kNoError; 7699 } 7700 7701 if (!ValidateCompressedTexDimensions( 7702 "glCompressedTexImage2D", level, width, height, internal_format) || 7703 !ValidateCompressedTexFuncData( 7704 "glCompressedTexImage2D", width, height, internal_format, image_size)) { 7705 return error::kNoError; 7706 } 7707 7708 if (!EnsureGPUMemoryAvailable(image_size)) { 7709 LOCAL_SET_GL_ERROR( 7710 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); 7711 return error::kNoError; 7712 } 7713 7714 if (texture->IsAttachedToFramebuffer()) { 7715 clear_state_dirty_ = true; 7716 } 7717 7718 scoped_ptr<int8[]> zero; 7719 if (!data) { 7720 zero.reset(new int8[image_size]); 7721 memset(zero.get(), 0, image_size); 7722 data = zero.get(); 7723 } 7724 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D"); 7725 glCompressedTexImage2D( 7726 target, level, internal_format, width, height, border, image_size, data); 7727 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D"); 7728 if (error == GL_NO_ERROR) { 7729 texture_manager()->SetLevelInfo( 7730 texture_ref, target, level, internal_format, 7731 width, height, 1, border, 0, 0, true); 7732 } 7733 return error::kNoError; 7734 } 7735 7736 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( 7737 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) { 7738 GLenum target = static_cast<GLenum>(c.target); 7739 GLint level = static_cast<GLint>(c.level); 7740 GLenum internal_format = static_cast<GLenum>(c.internalformat); 7741 GLsizei width = static_cast<GLsizei>(c.width); 7742 GLsizei height = static_cast<GLsizei>(c.height); 7743 GLint border = static_cast<GLint>(c.border); 7744 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 7745 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 7746 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 7747 const void* data = NULL; 7748 if (data_shm_id != 0 || data_shm_offset != 0) { 7749 data = GetSharedMemoryAs<const void*>( 7750 data_shm_id, data_shm_offset, image_size); 7751 if (!data) { 7752 return error::kOutOfBounds; 7753 } 7754 } 7755 return DoCompressedTexImage2D( 7756 target, level, internal_format, width, height, border, image_size, data); 7757 } 7758 7759 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( 7760 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) { 7761 GLenum target = static_cast<GLenum>(c.target); 7762 GLint level = static_cast<GLint>(c.level); 7763 GLenum internal_format = static_cast<GLenum>(c.internalformat); 7764 GLsizei width = static_cast<GLsizei>(c.width); 7765 GLsizei height = static_cast<GLsizei>(c.height); 7766 GLint border = static_cast<GLint>(c.border); 7767 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 7768 const void* data = GetImmediateDataAs<const void*>( 7769 c, image_size, immediate_data_size); 7770 if (!data) { 7771 return error::kOutOfBounds; 7772 } 7773 return DoCompressedTexImage2D( 7774 target, level, internal_format, width, height, border, image_size, data); 7775 } 7776 7777 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket( 7778 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) { 7779 GLenum target = static_cast<GLenum>(c.target); 7780 GLint level = static_cast<GLint>(c.level); 7781 GLenum internal_format = static_cast<GLenum>(c.internalformat); 7782 GLsizei width = static_cast<GLsizei>(c.width); 7783 GLsizei height = static_cast<GLsizei>(c.height); 7784 GLint border = static_cast<GLint>(c.border); 7785 Bucket* bucket = GetBucket(c.bucket_id); 7786 if (!bucket) { 7787 return error::kInvalidArguments; 7788 } 7789 uint32 data_size = bucket->size(); 7790 GLsizei imageSize = data_size; 7791 const void* data = bucket->GetData(0, data_size); 7792 if (!data) { 7793 return error::kInvalidArguments; 7794 } 7795 return DoCompressedTexImage2D( 7796 target, level, internal_format, width, height, border, 7797 imageSize, data); 7798 } 7799 7800 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket( 7801 uint32 immediate_data_size, 7802 const cmds::CompressedTexSubImage2DBucket& c) { 7803 GLenum target = static_cast<GLenum>(c.target); 7804 GLint level = static_cast<GLint>(c.level); 7805 GLint xoffset = static_cast<GLint>(c.xoffset); 7806 GLint yoffset = static_cast<GLint>(c.yoffset); 7807 GLsizei width = static_cast<GLsizei>(c.width); 7808 GLsizei height = static_cast<GLsizei>(c.height); 7809 GLenum format = static_cast<GLenum>(c.format); 7810 Bucket* bucket = GetBucket(c.bucket_id); 7811 if (!bucket) { 7812 return error::kInvalidArguments; 7813 } 7814 uint32 data_size = bucket->size(); 7815 GLsizei imageSize = data_size; 7816 const void* data = bucket->GetData(0, data_size); 7817 if (!data) { 7818 return error::kInvalidArguments; 7819 } 7820 if (!validators_->texture_target.IsValid(target)) { 7821 LOCAL_SET_GL_ERROR( 7822 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target"); 7823 return error::kNoError; 7824 } 7825 if (!validators_->compressed_texture_format.IsValid(format)) { 7826 LOCAL_SET_GL_ERROR_INVALID_ENUM( 7827 "glCompressedTexSubImage2D", format, "format"); 7828 return error::kNoError; 7829 } 7830 if (width < 0) { 7831 LOCAL_SET_GL_ERROR( 7832 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0"); 7833 return error::kNoError; 7834 } 7835 if (height < 0) { 7836 LOCAL_SET_GL_ERROR( 7837 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0"); 7838 return error::kNoError; 7839 } 7840 if (imageSize < 0) { 7841 LOCAL_SET_GL_ERROR( 7842 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0"); 7843 return error::kNoError; 7844 } 7845 DoCompressedTexSubImage2D( 7846 target, level, xoffset, yoffset, width, height, format, imageSize, data); 7847 return error::kNoError; 7848 } 7849 7850 bool GLES2DecoderImpl::ValidateTextureParameters( 7851 const char* function_name, 7852 GLenum target, GLenum format, GLenum type, GLint level) { 7853 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) { 7854 LOCAL_SET_GL_ERROR( 7855 GL_INVALID_OPERATION, function_name, 7856 (std::string("invalid type ") + 7857 GLES2Util::GetStringEnum(type) + " for format " + 7858 GLES2Util::GetStringEnum(format)).c_str()); 7859 return false; 7860 } 7861 7862 uint32 channels = GLES2Util::GetChannelsForFormat(format); 7863 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) { 7864 LOCAL_SET_GL_ERROR( 7865 GL_INVALID_OPERATION, function_name, 7866 (std::string("invalid type ") + 7867 GLES2Util::GetStringEnum(type) + " for format " + 7868 GLES2Util::GetStringEnum(format)).c_str()); 7869 return false; 7870 } 7871 return true; 7872 } 7873 7874 bool GLES2DecoderImpl::ValidateTexImage2D( 7875 const char* function_name, 7876 GLenum target, 7877 GLint level, 7878 GLenum internal_format, 7879 GLsizei width, 7880 GLsizei height, 7881 GLint border, 7882 GLenum format, 7883 GLenum type, 7884 const void* pixels, 7885 uint32 pixels_size) { 7886 if (!validators_->texture_target.IsValid(target)) { 7887 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target"); 7888 return false; 7889 } 7890 if (!validators_->texture_format.IsValid(internal_format)) { 7891 LOCAL_SET_GL_ERROR_INVALID_ENUM( 7892 function_name, internal_format, "internal_format"); 7893 return false; 7894 } 7895 if (!validators_->texture_format.IsValid(format)) { 7896 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); 7897 return false; 7898 } 7899 if (!validators_->pixel_type.IsValid(type)) { 7900 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type"); 7901 return false; 7902 } 7903 if (format != internal_format) { 7904 LOCAL_SET_GL_ERROR( 7905 GL_INVALID_OPERATION, function_name, "format != internalFormat"); 7906 return false; 7907 } 7908 if (!ValidateTextureParameters(function_name, target, format, type, level)) { 7909 return false; 7910 } 7911 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 7912 border != 0) { 7913 LOCAL_SET_GL_ERROR( 7914 GL_INVALID_VALUE, function_name, "dimensions out of range"); 7915 return false; 7916 } 7917 if ((GLES2Util::GetChannelsForFormat(format) & 7918 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) { 7919 LOCAL_SET_GL_ERROR( 7920 GL_INVALID_OPERATION, 7921 function_name, "can not supply data for depth or stencil textures"); 7922 return false; 7923 } 7924 TextureRef* texture_ref = GetTextureInfoForTarget(target); 7925 if (!texture_ref) { 7926 LOCAL_SET_GL_ERROR( 7927 GL_INVALID_OPERATION, function_name, "unknown texture for target"); 7928 return false; 7929 } 7930 if (texture_ref->texture()->IsImmutable()) { 7931 LOCAL_SET_GL_ERROR( 7932 GL_INVALID_OPERATION, function_name, "texture is immutable"); 7933 return false; 7934 } 7935 return true; 7936 } 7937 7938 void GLES2DecoderImpl::DoTexImage2D( 7939 GLenum target, 7940 GLint level, 7941 GLenum internal_format, 7942 GLsizei width, 7943 GLsizei height, 7944 GLint border, 7945 GLenum format, 7946 GLenum type, 7947 const void* pixels, 7948 uint32 pixels_size) { 7949 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format, 7950 width, height, border, format, type, pixels, pixels_size)) { 7951 return; 7952 } 7953 7954 if (!EnsureGPUMemoryAvailable(pixels_size)) { 7955 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory"); 7956 return; 7957 } 7958 7959 TextureRef* texture_ref = GetTextureInfoForTarget(target); 7960 Texture* texture = texture_ref->texture(); 7961 GLsizei tex_width = 0; 7962 GLsizei tex_height = 0; 7963 GLenum tex_type = 0; 7964 GLenum tex_format = 0; 7965 bool level_is_same = 7966 texture->GetLevelSize(target, level, &tex_width, &tex_height) && 7967 texture->GetLevelType(target, level, &tex_type, &tex_format) && 7968 width == tex_width && height == tex_height && 7969 type == tex_type && format == tex_format; 7970 7971 if (level_is_same && !pixels) { 7972 // Just set the level texture but mark the texture as uncleared. 7973 texture_manager()->SetLevelInfo( 7974 texture_ref, 7975 target, level, internal_format, width, height, 1, border, format, type, 7976 false); 7977 tex_image_2d_failed_ = false; 7978 return; 7979 } 7980 7981 if (texture->IsAttachedToFramebuffer()) { 7982 clear_state_dirty_ = true; 7983 } 7984 7985 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) { 7986 { 7987 ScopedTextureUploadTimer timer(this); 7988 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); 7989 } 7990 texture_manager()->SetLevelCleared(texture_ref, target, level, true); 7991 tex_image_2d_failed_ = false; 7992 return; 7993 } 7994 7995 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D"); 7996 { 7997 ScopedTextureUploadTimer timer(this); 7998 glTexImage2D( 7999 target, level, internal_format, width, height, border, format, type, 8000 pixels); 8001 } 8002 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D"); 8003 if (error == GL_NO_ERROR) { 8004 texture_manager()->SetLevelInfo( 8005 texture_ref, 8006 target, level, internal_format, width, height, 1, border, format, type, 8007 pixels != NULL); 8008 tex_image_2d_failed_ = false; 8009 } 8010 return; 8011 } 8012 8013 error::Error GLES2DecoderImpl::HandleTexImage2D( 8014 uint32 immediate_data_size, const cmds::TexImage2D& c) { 8015 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D"); 8016 tex_image_2d_failed_ = true; 8017 GLenum target = static_cast<GLenum>(c.target); 8018 GLint level = static_cast<GLint>(c.level); 8019 GLint internal_format = static_cast<GLint>(c.internalformat); 8020 GLsizei width = static_cast<GLsizei>(c.width); 8021 GLsizei height = static_cast<GLsizei>(c.height); 8022 GLint border = static_cast<GLint>(c.border); 8023 GLenum format = static_cast<GLenum>(c.format); 8024 GLenum type = static_cast<GLenum>(c.type); 8025 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 8026 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 8027 uint32 pixels_size; 8028 if (!GLES2Util::ComputeImageDataSizes( 8029 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 8030 NULL)) { 8031 return error::kOutOfBounds; 8032 } 8033 const void* pixels = NULL; 8034 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 8035 pixels = GetSharedMemoryAs<const void*>( 8036 pixels_shm_id, pixels_shm_offset, pixels_size); 8037 if (!pixels) { 8038 return error::kOutOfBounds; 8039 } 8040 } 8041 8042 DoTexImage2D( 8043 target, level, internal_format, width, height, border, format, type, 8044 pixels, pixels_size); 8045 return error::kNoError; 8046 } 8047 8048 error::Error GLES2DecoderImpl::HandleTexImage2DImmediate( 8049 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) { 8050 GLenum target = static_cast<GLenum>(c.target); 8051 GLint level = static_cast<GLint>(c.level); 8052 GLint internal_format = static_cast<GLint>(c.internalformat); 8053 GLsizei width = static_cast<GLsizei>(c.width); 8054 GLsizei height = static_cast<GLsizei>(c.height); 8055 GLint border = static_cast<GLint>(c.border); 8056 GLenum format = static_cast<GLenum>(c.format); 8057 GLenum type = static_cast<GLenum>(c.type); 8058 uint32 size; 8059 if (!GLES2Util::ComputeImageDataSizes( 8060 width, height, format, type, state_.unpack_alignment, &size, 8061 NULL, NULL)) { 8062 return error::kOutOfBounds; 8063 } 8064 const void* pixels = GetImmediateDataAs<const void*>( 8065 c, size, immediate_data_size); 8066 if (!pixels) { 8067 return error::kOutOfBounds; 8068 } 8069 DoTexImage2D( 8070 target, level, internal_format, width, height, border, format, type, 8071 pixels, size); 8072 return error::kNoError; 8073 } 8074 8075 void GLES2DecoderImpl::DoCompressedTexSubImage2D( 8076 GLenum target, 8077 GLint level, 8078 GLint xoffset, 8079 GLint yoffset, 8080 GLsizei width, 8081 GLsizei height, 8082 GLenum format, 8083 GLsizei image_size, 8084 const void * data) { 8085 TextureRef* texture_ref = GetTextureInfoForTarget(target); 8086 if (!texture_ref) { 8087 LOCAL_SET_GL_ERROR( 8088 GL_INVALID_OPERATION, 8089 "glCompressedTexSubImage2D", "unknown texture for target"); 8090 return; 8091 } 8092 Texture* texture = texture_ref->texture(); 8093 GLenum type = 0; 8094 GLenum internal_format = 0; 8095 if (!texture->GetLevelType(target, level, &type, &internal_format)) { 8096 LOCAL_SET_GL_ERROR( 8097 GL_INVALID_OPERATION, 8098 "glCompressedTexSubImage2D", "level does not exist."); 8099 return; 8100 } 8101 if (internal_format != format) { 8102 LOCAL_SET_GL_ERROR( 8103 GL_INVALID_OPERATION, 8104 "glCompressedTexSubImage2D", "format does not match internal format."); 8105 return; 8106 } 8107 if (!texture->ValidForTexture( 8108 target, level, xoffset, yoffset, width, height, format, type)) { 8109 LOCAL_SET_GL_ERROR( 8110 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions."); 8111 return; 8112 } 8113 8114 if (!ValidateCompressedTexFuncData( 8115 "glCompressedTexSubImage2D", width, height, format, image_size) || 8116 !ValidateCompressedTexSubDimensions( 8117 "glCompressedTexSubImage2D", 8118 target, level, xoffset, yoffset, width, height, format, texture)) { 8119 return; 8120 } 8121 8122 8123 // Note: There is no need to deal with texture cleared tracking here 8124 // because the validation above means you can only get here if the level 8125 // is already a matching compressed format and in that case 8126 // CompressedTexImage2D already cleared the texture. 8127 glCompressedTexSubImage2D( 8128 target, level, xoffset, yoffset, width, height, format, image_size, data); 8129 } 8130 8131 static void Clip( 8132 GLint start, GLint range, GLint sourceRange, 8133 GLint* out_start, GLint* out_range) { 8134 DCHECK(out_start); 8135 DCHECK(out_range); 8136 if (start < 0) { 8137 range += start; 8138 start = 0; 8139 } 8140 GLint end = start + range; 8141 if (end > sourceRange) { 8142 range -= end - sourceRange; 8143 } 8144 *out_start = start; 8145 *out_range = range; 8146 } 8147 8148 void GLES2DecoderImpl::DoCopyTexImage2D( 8149 GLenum target, 8150 GLint level, 8151 GLenum internal_format, 8152 GLint x, 8153 GLint y, 8154 GLsizei width, 8155 GLsizei height, 8156 GLint border) { 8157 DCHECK(!ShouldDeferReads()); 8158 TextureRef* texture_ref = GetTextureInfoForTarget(target); 8159 if (!texture_ref) { 8160 LOCAL_SET_GL_ERROR( 8161 GL_INVALID_OPERATION, 8162 "glCopyTexImage2D", "unknown texture for target"); 8163 return; 8164 } 8165 Texture* texture = texture_ref->texture(); 8166 if (texture->IsImmutable()) { 8167 LOCAL_SET_GL_ERROR( 8168 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable"); 8169 } 8170 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 8171 border != 0) { 8172 LOCAL_SET_GL_ERROR( 8173 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); 8174 return; 8175 } 8176 if (!ValidateTextureParameters( 8177 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) { 8178 return; 8179 } 8180 8181 // Check we have compatible formats. 8182 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 8183 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 8184 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); 8185 8186 if ((channels_needed & channels_exist) != channels_needed) { 8187 LOCAL_SET_GL_ERROR( 8188 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); 8189 return; 8190 } 8191 8192 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8193 LOCAL_SET_GL_ERROR( 8194 GL_INVALID_OPERATION, 8195 "glCopyTexImage2D", "can not be used with depth or stencil textures"); 8196 return; 8197 } 8198 8199 uint32 estimated_size = 0; 8200 if (!GLES2Util::ComputeImageDataSizes( 8201 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment, 8202 &estimated_size, NULL, NULL)) { 8203 LOCAL_SET_GL_ERROR( 8204 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large"); 8205 return; 8206 } 8207 8208 if (!EnsureGPUMemoryAvailable(estimated_size)) { 8209 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory"); 8210 return; 8211 } 8212 8213 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { 8214 return; 8215 } 8216 8217 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D"); 8218 ScopedResolvedFrameBufferBinder binder(this, false, true); 8219 gfx::Size size = GetBoundReadFrameBufferSize(); 8220 8221 if (texture->IsAttachedToFramebuffer()) { 8222 clear_state_dirty_ = true; 8223 } 8224 8225 // Clip to size to source dimensions 8226 GLint copyX = 0; 8227 GLint copyY = 0; 8228 GLint copyWidth = 0; 8229 GLint copyHeight = 0; 8230 Clip(x, width, size.width(), ©X, ©Width); 8231 Clip(y, height, size.height(), ©Y, ©Height); 8232 8233 if (copyX != x || 8234 copyY != y || 8235 copyWidth != width || 8236 copyHeight != height) { 8237 // some part was clipped so clear the texture. 8238 if (!ClearLevel( 8239 texture->service_id(), texture->target(), 8240 target, level, internal_format, GL_UNSIGNED_BYTE, width, height, 8241 texture->IsImmutable())) { 8242 LOCAL_SET_GL_ERROR( 8243 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); 8244 return; 8245 } 8246 if (copyHeight > 0 && copyWidth > 0) { 8247 GLint dx = copyX - x; 8248 GLint dy = copyY - y; 8249 GLint destX = dx; 8250 GLint destY = dy; 8251 glCopyTexSubImage2D(target, level, 8252 destX, destY, copyX, copyY, 8253 copyWidth, copyHeight); 8254 } 8255 } else { 8256 glCopyTexImage2D(target, level, internal_format, 8257 copyX, copyY, copyWidth, copyHeight, border); 8258 } 8259 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D"); 8260 if (error == GL_NO_ERROR) { 8261 texture_manager()->SetLevelInfo( 8262 texture_ref, target, level, internal_format, width, height, 1, 8263 border, internal_format, GL_UNSIGNED_BYTE, true); 8264 } 8265 } 8266 8267 void GLES2DecoderImpl::DoCopyTexSubImage2D( 8268 GLenum target, 8269 GLint level, 8270 GLint xoffset, 8271 GLint yoffset, 8272 GLint x, 8273 GLint y, 8274 GLsizei width, 8275 GLsizei height) { 8276 DCHECK(!ShouldDeferReads()); 8277 TextureRef* texture_ref = GetTextureInfoForTarget(target); 8278 if (!texture_ref) { 8279 LOCAL_SET_GL_ERROR( 8280 GL_INVALID_OPERATION, 8281 "glCopyTexSubImage2D", "unknown texture for target"); 8282 return; 8283 } 8284 Texture* texture = texture_ref->texture(); 8285 GLenum type = 0; 8286 GLenum format = 0; 8287 if (!texture->GetLevelType(target, level, &type, &format) || 8288 !texture->ValidForTexture( 8289 target, level, xoffset, yoffset, width, height, format, type)) { 8290 LOCAL_SET_GL_ERROR( 8291 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions."); 8292 return; 8293 } 8294 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { 8295 LOCAL_SET_GL_ERROR( 8296 GL_INVALID_OPERATION, 8297 "glCopyTexSubImage2D", "async upload pending for texture"); 8298 return; 8299 } 8300 8301 // Check we have compatible formats. 8302 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 8303 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 8304 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); 8305 8306 if (!channels_needed || 8307 (channels_needed & channels_exist) != channels_needed) { 8308 LOCAL_SET_GL_ERROR( 8309 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); 8310 return; 8311 } 8312 8313 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8314 LOCAL_SET_GL_ERROR( 8315 GL_INVALID_OPERATION, 8316 "glCopySubImage2D", "can not be used with depth or stencil textures"); 8317 return; 8318 } 8319 8320 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { 8321 return; 8322 } 8323 8324 ScopedResolvedFrameBufferBinder binder(this, false, true); 8325 gfx::Size size = GetBoundReadFrameBufferSize(); 8326 GLint copyX = 0; 8327 GLint copyY = 0; 8328 GLint copyWidth = 0; 8329 GLint copyHeight = 0; 8330 Clip(x, width, size.width(), ©X, ©Width); 8331 Clip(y, height, size.height(), ©Y, ©Height); 8332 8333 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) { 8334 LOCAL_SET_GL_ERROR( 8335 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); 8336 return; 8337 } 8338 8339 if (copyX != x || 8340 copyY != y || 8341 copyWidth != width || 8342 copyHeight != height) { 8343 // some part was clipped so clear the sub rect. 8344 uint32 pixels_size = 0; 8345 if (!GLES2Util::ComputeImageDataSizes( 8346 width, height, format, type, state_.unpack_alignment, &pixels_size, 8347 NULL, NULL)) { 8348 LOCAL_SET_GL_ERROR( 8349 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); 8350 return; 8351 } 8352 scoped_ptr<char[]> zero(new char[pixels_size]); 8353 memset(zero.get(), 0, pixels_size); 8354 glTexSubImage2D( 8355 target, level, xoffset, yoffset, width, height, 8356 format, type, zero.get()); 8357 } 8358 8359 if (copyHeight > 0 && copyWidth > 0) { 8360 GLint dx = copyX - x; 8361 GLint dy = copyY - y; 8362 GLint destX = xoffset + dx; 8363 GLint destY = yoffset + dy; 8364 glCopyTexSubImage2D(target, level, 8365 destX, destY, copyX, copyY, 8366 copyWidth, copyHeight); 8367 } 8368 } 8369 8370 bool GLES2DecoderImpl::ValidateTexSubImage2D( 8371 error::Error* error, 8372 const char* function_name, 8373 GLenum target, 8374 GLint level, 8375 GLint xoffset, 8376 GLint yoffset, 8377 GLsizei width, 8378 GLsizei height, 8379 GLenum format, 8380 GLenum type, 8381 const void * data) { 8382 (*error) = error::kNoError; 8383 if (!validators_->texture_target.IsValid(target)) { 8384 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target"); 8385 return false; 8386 } 8387 if (width < 0) { 8388 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0"); 8389 return false; 8390 } 8391 if (height < 0) { 8392 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0"); 8393 return false; 8394 } 8395 if (!validators_->texture_format.IsValid(format)) { 8396 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format"); 8397 return false; 8398 } 8399 if (!validators_->pixel_type.IsValid(type)) { 8400 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type"); 8401 return false; 8402 } 8403 TextureRef* texture_ref = GetTextureInfoForTarget(target); 8404 if (!texture_ref) { 8405 LOCAL_SET_GL_ERROR( 8406 GL_INVALID_OPERATION, 8407 function_name, "unknown texture for target"); 8408 return false; 8409 } 8410 Texture* texture = texture_ref->texture(); 8411 GLenum current_type = 0; 8412 GLenum internal_format = 0; 8413 if (!texture->GetLevelType(target, level, ¤t_type, &internal_format)) { 8414 LOCAL_SET_GL_ERROR( 8415 GL_INVALID_OPERATION, function_name, "level does not exist."); 8416 return false; 8417 } 8418 if (format != internal_format) { 8419 LOCAL_SET_GL_ERROR( 8420 GL_INVALID_OPERATION, 8421 function_name, "format does not match internal format."); 8422 return false; 8423 } 8424 if (type != current_type) { 8425 LOCAL_SET_GL_ERROR( 8426 GL_INVALID_OPERATION, 8427 function_name, "type does not match type of texture."); 8428 return false; 8429 } 8430 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { 8431 LOCAL_SET_GL_ERROR( 8432 GL_INVALID_OPERATION, 8433 function_name, "async upload pending for texture"); 8434 return false; 8435 } 8436 if (!texture->ValidForTexture( 8437 target, level, xoffset, yoffset, width, height, format, type)) { 8438 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions."); 8439 return false; 8440 } 8441 if ((GLES2Util::GetChannelsForFormat(format) & 8442 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 8443 LOCAL_SET_GL_ERROR( 8444 GL_INVALID_OPERATION, 8445 function_name, "can not supply data for depth or stencil textures"); 8446 return false; 8447 } 8448 if (data == NULL) { 8449 (*error) = error::kOutOfBounds; 8450 return false; 8451 } 8452 return true; 8453 } 8454 8455 error::Error GLES2DecoderImpl::DoTexSubImage2D( 8456 GLenum target, 8457 GLint level, 8458 GLint xoffset, 8459 GLint yoffset, 8460 GLsizei width, 8461 GLsizei height, 8462 GLenum format, 8463 GLenum type, 8464 const void * data) { 8465 error::Error error = error::kNoError; 8466 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level, 8467 xoffset, yoffset, width, height, format, type, data)) { 8468 return error; 8469 } 8470 TextureRef* texture_ref = GetTextureInfoForTarget(target); 8471 Texture* texture = texture_ref->texture(); 8472 GLsizei tex_width = 0; 8473 GLsizei tex_height = 0; 8474 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height); 8475 DCHECK(ok); 8476 if (xoffset != 0 || yoffset != 0 || 8477 width != tex_width || height != tex_height) { 8478 if (!texture_manager()->ClearTextureLevel(this, texture_ref, 8479 target, level)) { 8480 LOCAL_SET_GL_ERROR( 8481 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); 8482 return error::kNoError; 8483 } 8484 ScopedTextureUploadTimer timer(this); 8485 glTexSubImage2D( 8486 target, level, xoffset, yoffset, width, height, format, type, data); 8487 return error::kNoError; 8488 } 8489 8490 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) { 8491 ScopedTextureUploadTimer timer(this); 8492 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the 8493 // same as internal_foramt. If that changes we'll need to look them up. 8494 glTexImage2D( 8495 target, level, format, width, height, 0, format, type, data); 8496 } else { 8497 ScopedTextureUploadTimer timer(this); 8498 glTexSubImage2D( 8499 target, level, xoffset, yoffset, width, height, format, type, data); 8500 } 8501 texture_manager()->SetLevelCleared(texture_ref, target, level, true); 8502 return error::kNoError; 8503 } 8504 8505 error::Error GLES2DecoderImpl::HandleTexSubImage2D( 8506 uint32 immediate_data_size, const cmds::TexSubImage2D& c) { 8507 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); 8508 GLboolean internal = static_cast<GLboolean>(c.internal); 8509 if (internal == GL_TRUE && tex_image_2d_failed_) 8510 return error::kNoError; 8511 8512 GLenum target = static_cast<GLenum>(c.target); 8513 GLint level = static_cast<GLint>(c.level); 8514 GLint xoffset = static_cast<GLint>(c.xoffset); 8515 GLint yoffset = static_cast<GLint>(c.yoffset); 8516 GLsizei width = static_cast<GLsizei>(c.width); 8517 GLsizei height = static_cast<GLsizei>(c.height); 8518 GLenum format = static_cast<GLenum>(c.format); 8519 GLenum type = static_cast<GLenum>(c.type); 8520 uint32 data_size; 8521 if (!GLES2Util::ComputeImageDataSizes( 8522 width, height, format, type, state_.unpack_alignment, &data_size, 8523 NULL, NULL)) { 8524 return error::kOutOfBounds; 8525 } 8526 const void* pixels = GetSharedMemoryAs<const void*>( 8527 c.pixels_shm_id, c.pixels_shm_offset, data_size); 8528 return DoTexSubImage2D( 8529 target, level, xoffset, yoffset, width, height, format, type, pixels); 8530 } 8531 8532 error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate( 8533 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) { 8534 GLboolean internal = static_cast<GLboolean>(c.internal); 8535 if (internal == GL_TRUE && tex_image_2d_failed_) 8536 return error::kNoError; 8537 8538 GLenum target = static_cast<GLenum>(c.target); 8539 GLint level = static_cast<GLint>(c.level); 8540 GLint xoffset = static_cast<GLint>(c.xoffset); 8541 GLint yoffset = static_cast<GLint>(c.yoffset); 8542 GLsizei width = static_cast<GLsizei>(c.width); 8543 GLsizei height = static_cast<GLsizei>(c.height); 8544 GLenum format = static_cast<GLenum>(c.format); 8545 GLenum type = static_cast<GLenum>(c.type); 8546 uint32 data_size; 8547 if (!GLES2Util::ComputeImageDataSizes( 8548 width, height, format, type, state_.unpack_alignment, &data_size, 8549 NULL, NULL)) { 8550 return error::kOutOfBounds; 8551 } 8552 const void* pixels = GetImmediateDataAs<const void*>( 8553 c, data_size, immediate_data_size); 8554 return DoTexSubImage2D( 8555 target, level, xoffset, yoffset, width, height, format, type, pixels); 8556 } 8557 8558 error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( 8559 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) { 8560 GLuint index = static_cast<GLuint>(c.index); 8561 GLenum pname = static_cast<GLenum>(c.pname); 8562 typedef cmds::GetVertexAttribPointerv::Result Result; 8563 Result* result = GetSharedMemoryAs<Result*>( 8564 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1)); 8565 if (!result) { 8566 return error::kOutOfBounds; 8567 } 8568 // Check that the client initialized the result. 8569 if (result->size != 0) { 8570 return error::kInvalidArguments; 8571 } 8572 if (!validators_->vertex_pointer.IsValid(pname)) { 8573 LOCAL_SET_GL_ERROR_INVALID_ENUM( 8574 "glGetVertexAttribPointerv", pname, "pname"); 8575 return error::kNoError; 8576 } 8577 if (index >= group_->max_vertex_attribs()) { 8578 LOCAL_SET_GL_ERROR( 8579 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range."); 8580 return error::kNoError; 8581 } 8582 result->SetNumResults(1); 8583 *result->GetData() = 8584 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset(); 8585 return error::kNoError; 8586 } 8587 8588 bool GLES2DecoderImpl::GetUniformSetup( 8589 GLuint program_id, GLint fake_location, 8590 uint32 shm_id, uint32 shm_offset, 8591 error::Error* error, GLint* real_location, 8592 GLuint* service_id, void** result_pointer, GLenum* result_type) { 8593 DCHECK(error); 8594 DCHECK(service_id); 8595 DCHECK(result_pointer); 8596 DCHECK(result_type); 8597 DCHECK(real_location); 8598 *error = error::kNoError; 8599 // Make sure we have enough room for the result on failure. 8600 SizedResult<GLint>* result; 8601 result = GetSharedMemoryAs<SizedResult<GLint>*>( 8602 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0)); 8603 if (!result) { 8604 *error = error::kOutOfBounds; 8605 return false; 8606 } 8607 *result_pointer = result; 8608 // Set the result size to 0 so the client does not have to check for success. 8609 result->SetNumResults(0); 8610 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform"); 8611 if (!program) { 8612 return false; 8613 } 8614 if (!program->IsValid()) { 8615 // Program was not linked successfully. (ie, glLinkProgram) 8616 LOCAL_SET_GL_ERROR( 8617 GL_INVALID_OPERATION, "glGetUniform", "program not linked"); 8618 return false; 8619 } 8620 *service_id = program->service_id(); 8621 GLint array_index = -1; 8622 const Program::UniformInfo* uniform_info = 8623 program->GetUniformInfoByFakeLocation( 8624 fake_location, real_location, &array_index); 8625 if (!uniform_info) { 8626 // No such location. 8627 LOCAL_SET_GL_ERROR( 8628 GL_INVALID_OPERATION, "glGetUniform", "unknown location"); 8629 return false; 8630 } 8631 GLenum type = uniform_info->type; 8632 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type); 8633 if (size == 0) { 8634 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type"); 8635 return false; 8636 } 8637 result = GetSharedMemoryAs<SizedResult<GLint>*>( 8638 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size)); 8639 if (!result) { 8640 *error = error::kOutOfBounds; 8641 return false; 8642 } 8643 result->size = size; 8644 *result_type = type; 8645 return true; 8646 } 8647 8648 error::Error GLES2DecoderImpl::HandleGetUniformiv( 8649 uint32 immediate_data_size, const cmds::GetUniformiv& c) { 8650 GLuint program = c.program; 8651 GLint fake_location = c.location; 8652 GLuint service_id; 8653 GLenum result_type; 8654 GLint real_location = -1; 8655 Error error; 8656 void* result; 8657 if (GetUniformSetup( 8658 program, fake_location, c.params_shm_id, c.params_shm_offset, 8659 &error, &real_location, &service_id, &result, &result_type)) { 8660 glGetUniformiv( 8661 service_id, real_location, 8662 static_cast<cmds::GetUniformiv::Result*>(result)->GetData()); 8663 } 8664 return error; 8665 } 8666 8667 error::Error GLES2DecoderImpl::HandleGetUniformfv( 8668 uint32 immediate_data_size, const cmds::GetUniformfv& c) { 8669 GLuint program = c.program; 8670 GLint fake_location = c.location; 8671 GLuint service_id; 8672 GLint real_location = -1; 8673 Error error; 8674 typedef cmds::GetUniformfv::Result Result; 8675 Result* result; 8676 GLenum result_type; 8677 if (GetUniformSetup( 8678 program, fake_location, c.params_shm_id, c.params_shm_offset, 8679 &error, &real_location, &service_id, 8680 reinterpret_cast<void**>(&result), &result_type)) { 8681 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 || 8682 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) { 8683 GLsizei num_values = result->GetNumResults(); 8684 scoped_ptr<GLint[]> temp(new GLint[num_values]); 8685 glGetUniformiv(service_id, real_location, temp.get()); 8686 GLfloat* dst = result->GetData(); 8687 for (GLsizei ii = 0; ii < num_values; ++ii) { 8688 dst[ii] = (temp[ii] != 0); 8689 } 8690 } else { 8691 glGetUniformfv(service_id, real_location, result->GetData()); 8692 } 8693 } 8694 return error; 8695 } 8696 8697 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( 8698 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) { 8699 GLenum shader_type = static_cast<GLenum>(c.shadertype); 8700 GLenum precision_type = static_cast<GLenum>(c.precisiontype); 8701 typedef cmds::GetShaderPrecisionFormat::Result Result; 8702 Result* result = GetSharedMemoryAs<Result*>( 8703 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8704 if (!result) { 8705 return error::kOutOfBounds; 8706 } 8707 // Check that the client initialized the result. 8708 if (result->success != 0) { 8709 return error::kInvalidArguments; 8710 } 8711 if (!validators_->shader_type.IsValid(shader_type)) { 8712 LOCAL_SET_GL_ERROR_INVALID_ENUM( 8713 "glGetShaderPrecisionFormat", shader_type, "shader_type"); 8714 return error::kNoError; 8715 } 8716 if (!validators_->shader_precision.IsValid(precision_type)) { 8717 LOCAL_SET_GL_ERROR_INVALID_ENUM( 8718 "glGetShaderPrecisionFormat", precision_type, "precision_type"); 8719 return error::kNoError; 8720 } 8721 8722 result->success = 1; // true 8723 8724 GLint range[2] = { 0, 0 }; 8725 GLint precision = 0; 8726 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision); 8727 8728 result->min_range = range[0]; 8729 result->max_range = range[1]; 8730 result->precision = precision; 8731 8732 return error::kNoError; 8733 } 8734 8735 error::Error GLES2DecoderImpl::HandleGetAttachedShaders( 8736 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) { 8737 uint32 result_size = c.result_size; 8738 GLuint program_id = static_cast<GLuint>(c.program); 8739 Program* program = GetProgramInfoNotShader( 8740 program_id, "glGetAttachedShaders"); 8741 if (!program) { 8742 return error::kNoError; 8743 } 8744 typedef cmds::GetAttachedShaders::Result Result; 8745 uint32 max_count = Result::ComputeMaxResults(result_size); 8746 Result* result = GetSharedMemoryAs<Result*>( 8747 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count)); 8748 if (!result) { 8749 return error::kOutOfBounds; 8750 } 8751 // Check that the client initialized the result. 8752 if (result->size != 0) { 8753 return error::kInvalidArguments; 8754 } 8755 GLsizei count = 0; 8756 glGetAttachedShaders( 8757 program->service_id(), max_count, &count, result->GetData()); 8758 for (GLsizei ii = 0; ii < count; ++ii) { 8759 if (!shader_manager()->GetClientId(result->GetData()[ii], 8760 &result->GetData()[ii])) { 8761 NOTREACHED(); 8762 return error::kGenericError; 8763 } 8764 } 8765 result->SetNumResults(count); 8766 return error::kNoError; 8767 } 8768 8769 error::Error GLES2DecoderImpl::HandleGetActiveUniform( 8770 uint32 immediate_data_size, const cmds::GetActiveUniform& c) { 8771 GLuint program_id = c.program; 8772 GLuint index = c.index; 8773 uint32 name_bucket_id = c.name_bucket_id; 8774 typedef cmds::GetActiveUniform::Result Result; 8775 Result* result = GetSharedMemoryAs<Result*>( 8776 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8777 if (!result) { 8778 return error::kOutOfBounds; 8779 } 8780 // Check that the client initialized the result. 8781 if (result->success != 0) { 8782 return error::kInvalidArguments; 8783 } 8784 Program* program = GetProgramInfoNotShader( 8785 program_id, "glGetActiveUniform"); 8786 if (!program) { 8787 return error::kNoError; 8788 } 8789 const Program::UniformInfo* uniform_info = 8790 program->GetUniformInfo(index); 8791 if (!uniform_info) { 8792 LOCAL_SET_GL_ERROR( 8793 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range"); 8794 return error::kNoError; 8795 } 8796 result->success = 1; // true. 8797 result->size = uniform_info->size; 8798 result->type = uniform_info->type; 8799 Bucket* bucket = CreateBucket(name_bucket_id); 8800 bucket->SetFromString(uniform_info->name.c_str()); 8801 return error::kNoError; 8802 } 8803 8804 error::Error GLES2DecoderImpl::HandleGetActiveAttrib( 8805 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) { 8806 GLuint program_id = c.program; 8807 GLuint index = c.index; 8808 uint32 name_bucket_id = c.name_bucket_id; 8809 typedef cmds::GetActiveAttrib::Result Result; 8810 Result* result = GetSharedMemoryAs<Result*>( 8811 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8812 if (!result) { 8813 return error::kOutOfBounds; 8814 } 8815 // Check that the client initialized the result. 8816 if (result->success != 0) { 8817 return error::kInvalidArguments; 8818 } 8819 Program* program = GetProgramInfoNotShader( 8820 program_id, "glGetActiveAttrib"); 8821 if (!program) { 8822 return error::kNoError; 8823 } 8824 const Program::VertexAttrib* attrib_info = 8825 program->GetAttribInfo(index); 8826 if (!attrib_info) { 8827 LOCAL_SET_GL_ERROR( 8828 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range"); 8829 return error::kNoError; 8830 } 8831 result->success = 1; // true. 8832 result->size = attrib_info->size; 8833 result->type = attrib_info->type; 8834 Bucket* bucket = CreateBucket(name_bucket_id); 8835 bucket->SetFromString(attrib_info->name.c_str()); 8836 return error::kNoError; 8837 } 8838 8839 error::Error GLES2DecoderImpl::HandleShaderBinary( 8840 uint32 immediate_data_size, const cmds::ShaderBinary& c) { 8841 #if 1 // No binary shader support. 8842 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported"); 8843 return error::kNoError; 8844 #else 8845 GLsizei n = static_cast<GLsizei>(c.n); 8846 if (n < 0) { 8847 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0"); 8848 return error::kNoError; 8849 } 8850 GLsizei length = static_cast<GLsizei>(c.length); 8851 if (length < 0) { 8852 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0"); 8853 return error::kNoError; 8854 } 8855 uint32 data_size; 8856 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 8857 return error::kOutOfBounds; 8858 } 8859 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>( 8860 c.shaders_shm_id, c.shaders_shm_offset, data_size); 8861 GLenum binaryformat = static_cast<GLenum>(c.binaryformat); 8862 const void* binary = GetSharedMemoryAs<const void*>( 8863 c.binary_shm_id, c.binary_shm_offset, length); 8864 if (shaders == NULL || binary == NULL) { 8865 return error::kOutOfBounds; 8866 } 8867 scoped_array<GLuint> service_ids(new GLuint[n]); 8868 for (GLsizei ii = 0; ii < n; ++ii) { 8869 Shader* shader = GetShader(shaders[ii]); 8870 if (!shader) { 8871 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader"); 8872 return error::kNoError; 8873 } 8874 service_ids[ii] = shader->service_id(); 8875 } 8876 // TODO(gman): call glShaderBinary 8877 return error::kNoError; 8878 #endif 8879 } 8880 8881 void GLES2DecoderImpl::DoSwapBuffers() { 8882 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 8883 8884 int this_frame_number = frame_number_++; 8885 // TRACE_EVENT for gpu tests: 8886 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency", 8887 TRACE_EVENT_SCOPE_THREAD, 8888 "GLImpl", static_cast<int>(gfx::GetGLImplementation()), 8889 "width", (is_offscreen ? offscreen_size_.width() : 8890 surface_->GetSize().width())); 8891 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers", 8892 "offscreen", is_offscreen, 8893 "frame", this_frame_number); 8894 // If offscreen then don't actually SwapBuffers to the display. Just copy 8895 // the rendered frame to another frame buffer. 8896 if (is_offscreen) { 8897 TRACE_EVENT2("gpu", "Offscreen", 8898 "width", offscreen_size_.width(), "height", offscreen_size_.height()); 8899 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { 8900 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, 8901 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will 8902 // fix this. 8903 if (workarounds().needs_offscreen_buffer_workaround) { 8904 offscreen_saved_frame_buffer_->Create(); 8905 glFinish(); 8906 } 8907 8908 // Allocate the offscreen saved color texture. 8909 DCHECK(offscreen_saved_color_format_); 8910 offscreen_saved_color_texture_->AllocateStorage( 8911 offscreen_size_, offscreen_saved_color_format_, false); 8912 8913 offscreen_saved_frame_buffer_->AttachRenderTexture( 8914 offscreen_saved_color_texture_.get()); 8915 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) { 8916 if (offscreen_saved_frame_buffer_->CheckStatus() != 8917 GL_FRAMEBUFFER_COMPLETE) { 8918 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 8919 << "because offscreen saved FBO was incomplete."; 8920 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); 8921 return; 8922 } 8923 8924 // Clear the offscreen color texture. 8925 // TODO(piman): Is this still necessary? 8926 { 8927 ScopedFrameBufferBinder binder(this, 8928 offscreen_saved_frame_buffer_->id()); 8929 glClearColor(0, 0, 0, 0); 8930 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 8931 glDisable(GL_SCISSOR_TEST); 8932 glClear(GL_COLOR_BUFFER_BIT); 8933 RestoreClearState(); 8934 } 8935 } 8936 8937 UpdateParentTextureInfo(); 8938 } 8939 8940 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0) 8941 return; 8942 ScopedGLErrorSuppressor suppressor( 8943 "GLES2DecoderImpl::DoSwapBuffers", this); 8944 8945 if (IsOffscreenBufferMultisampled()) { 8946 // For multisampled buffers, resolve the frame buffer. 8947 ScopedResolvedFrameBufferBinder binder(this, true, false); 8948 } else { 8949 ScopedFrameBufferBinder binder(this, 8950 offscreen_target_frame_buffer_->id()); 8951 8952 if (offscreen_target_buffer_preserved_) { 8953 // Copy the target frame buffer to the saved offscreen texture. 8954 offscreen_saved_color_texture_->Copy( 8955 offscreen_saved_color_texture_->size(), 8956 offscreen_saved_color_format_); 8957 } else { 8958 // Flip the textures in the parent context via the texture manager. 8959 if (!!offscreen_saved_color_texture_info_.get()) 8960 offscreen_saved_color_texture_info_->texture()-> 8961 SetServiceId(offscreen_target_color_texture_->id()); 8962 8963 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_); 8964 offscreen_target_frame_buffer_->AttachRenderTexture( 8965 offscreen_target_color_texture_.get()); 8966 } 8967 8968 // Ensure the side effects of the copy are visible to the parent 8969 // context. There is no need to do this for ANGLE because it uses a 8970 // single D3D device for all contexts. 8971 if (!IsAngle()) 8972 glFlush(); 8973 } 8974 } else { 8975 TRACE_EVENT2("gpu", "Onscreen", 8976 "width", surface_->GetSize().width(), 8977 "height", surface_->GetSize().height()); 8978 if (!surface_->SwapBuffers()) { 8979 LOG(ERROR) << "Context lost because SwapBuffers failed."; 8980 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); 8981 } 8982 } 8983 } 8984 8985 error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM( 8986 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) { 8987 Bucket* bucket = GetBucket(c.bucket_id); 8988 if (!bucket || bucket->size() == 0) { 8989 return error::kInvalidArguments; 8990 } 8991 typedef cmds::EnableFeatureCHROMIUM::Result Result; 8992 Result* result = GetSharedMemoryAs<Result*>( 8993 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8994 if (!result) { 8995 return error::kOutOfBounds; 8996 } 8997 // Check that the client initialized the result. 8998 if (*result != 0) { 8999 return error::kInvalidArguments; 9000 } 9001 std::string feature_str; 9002 if (!bucket->GetAsString(&feature_str)) { 9003 return error::kInvalidArguments; 9004 } 9005 9006 // TODO(gman): make this some kind of table to function pointer thingy. 9007 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) { 9008 buffer_manager()->set_allow_buffers_on_multiple_targets(true); 9009 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) { 9010 buffer_manager()->set_allow_buffers_on_multiple_targets(true); 9011 // TODO(gman): decide how to remove the need for this const_cast. 9012 // I could make validators_ non const but that seems bad as this is the only 9013 // place it is needed. I could make some special friend class of validators 9014 // just to allow this to set them. That seems silly. I could refactor this 9015 // code to use the extension mechanism or the initialization attributes to 9016 // turn this feature on. Given that the only real point of this is to make 9017 // the conformance tests pass and given that there is lots of real work that 9018 // needs to be done it seems like refactoring for one to one of those 9019 // methods is a very low priority. 9020 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED); 9021 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) { 9022 force_webgl_glsl_validation_ = true; 9023 InitializeShaderTranslator(); 9024 } else { 9025 return error::kNoError; 9026 } 9027 9028 *result = 1; // true. 9029 return error::kNoError; 9030 } 9031 9032 error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM( 9033 uint32 immediate_data_size, 9034 const cmds::GetRequestableExtensionsCHROMIUM& c) { 9035 Bucket* bucket = CreateBucket(c.bucket_id); 9036 scoped_refptr<FeatureInfo> info(new FeatureInfo()); 9037 info->Initialize(disallowed_features_, NULL); 9038 bucket->SetFromString(info->extensions().c_str()); 9039 return error::kNoError; 9040 } 9041 9042 error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM( 9043 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) { 9044 Bucket* bucket = GetBucket(c.bucket_id); 9045 if (!bucket || bucket->size() == 0) { 9046 return error::kInvalidArguments; 9047 } 9048 std::string feature_str; 9049 if (!bucket->GetAsString(&feature_str)) { 9050 return error::kInvalidArguments; 9051 } 9052 9053 bool desire_webgl_glsl_validation = 9054 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos; 9055 bool desire_standard_derivatives = false; 9056 bool desire_frag_depth = false; 9057 bool desire_draw_buffers = false; 9058 if (force_webgl_glsl_validation_) { 9059 desire_standard_derivatives = 9060 feature_str.find("GL_OES_standard_derivatives") != std::string::npos; 9061 desire_frag_depth = 9062 feature_str.find("GL_EXT_frag_depth") != std::string::npos; 9063 desire_draw_buffers = 9064 feature_str.find("GL_EXT_draw_buffers") != std::string::npos; 9065 } 9066 9067 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ || 9068 desire_standard_derivatives != derivatives_explicitly_enabled_ || 9069 desire_frag_depth != frag_depth_explicitly_enabled_ || 9070 desire_draw_buffers != draw_buffers_explicitly_enabled_) { 9071 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation; 9072 derivatives_explicitly_enabled_ |= desire_standard_derivatives; 9073 frag_depth_explicitly_enabled_ |= desire_frag_depth; 9074 draw_buffers_explicitly_enabled_ |= desire_draw_buffers; 9075 InitializeShaderTranslator(); 9076 } 9077 9078 UpdateCapabilities(); 9079 9080 return error::kNoError; 9081 } 9082 9083 error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM( 9084 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) { 9085 GLuint count = c.count; 9086 uint32 pnames_size; 9087 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) { 9088 return error::kOutOfBounds; 9089 } 9090 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>( 9091 c.pnames_shm_id, c.pnames_shm_offset, pnames_size); 9092 if (pnames == NULL) { 9093 return error::kOutOfBounds; 9094 } 9095 9096 // We have to copy them since we use them twice so the client 9097 // can't change them between the time we validate them and the time we use 9098 // them. 9099 scoped_ptr<GLenum[]> enums(new GLenum[count]); 9100 memcpy(enums.get(), pnames, pnames_size); 9101 9102 // Count up the space needed for the result. 9103 uint32 num_results = 0; 9104 for (GLuint ii = 0; ii < count; ++ii) { 9105 uint32 num = util_.GLGetNumValuesReturned(enums[ii]); 9106 if (num == 0) { 9107 LOCAL_SET_GL_ERROR_INVALID_ENUM( 9108 "glGetMulitpleCHROMIUM", enums[ii], "pname"); 9109 return error::kNoError; 9110 } 9111 // Num will never be more than 4. 9112 DCHECK_LE(num, 4u); 9113 if (!SafeAddUint32(num_results, num, &num_results)) { 9114 return error::kOutOfBounds; 9115 } 9116 } 9117 9118 uint32 result_size = 0; 9119 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) { 9120 return error::kOutOfBounds; 9121 } 9122 9123 if (result_size != static_cast<uint32>(c.size)) { 9124 LOCAL_SET_GL_ERROR( 9125 GL_INVALID_VALUE, 9126 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE"); 9127 return error::kNoError; 9128 } 9129 9130 GLint* results = GetSharedMemoryAs<GLint*>( 9131 c.results_shm_id, c.results_shm_offset, result_size); 9132 if (results == NULL) { 9133 return error::kOutOfBounds; 9134 } 9135 9136 // Check the results have been cleared in case the context was lost. 9137 for (uint32 ii = 0; ii < num_results; ++ii) { 9138 if (results[ii]) { 9139 return error::kInvalidArguments; 9140 } 9141 } 9142 9143 // Get each result. 9144 GLint* start = results; 9145 for (GLuint ii = 0; ii < count; ++ii) { 9146 GLsizei num_written = 0; 9147 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) && 9148 !GetHelper(enums[ii], results, &num_written)) { 9149 DoGetIntegerv(enums[ii], results); 9150 } 9151 results += num_written; 9152 } 9153 9154 // Just to verify. Should this be a DCHECK? 9155 if (static_cast<uint32>(results - start) != num_results) { 9156 return error::kOutOfBounds; 9157 } 9158 9159 return error::kNoError; 9160 } 9161 9162 error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM( 9163 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) { 9164 GLuint program_id = static_cast<GLuint>(c.program); 9165 uint32 bucket_id = c.bucket_id; 9166 Bucket* bucket = CreateBucket(bucket_id); 9167 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail. 9168 Program* program = NULL; 9169 program = GetProgram(program_id); 9170 if (!program || !program->IsValid()) { 9171 return error::kNoError; 9172 } 9173 program->GetProgramInfo(program_manager(), bucket); 9174 return error::kNoError; 9175 } 9176 9177 error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { 9178 switch (reset_status_) { 9179 case GL_NO_ERROR: 9180 // TODO(kbr): improve the precision of the error code in this case. 9181 // Consider delegating to context for error code if MakeCurrent fails. 9182 return error::kUnknown; 9183 case GL_GUILTY_CONTEXT_RESET_ARB: 9184 return error::kGuilty; 9185 case GL_INNOCENT_CONTEXT_RESET_ARB: 9186 return error::kInnocent; 9187 case GL_UNKNOWN_CONTEXT_RESET_ARB: 9188 return error::kUnknown; 9189 } 9190 9191 NOTREACHED(); 9192 return error::kUnknown; 9193 } 9194 9195 bool GLES2DecoderImpl::WasContextLost() { 9196 if (reset_status_ != GL_NO_ERROR) { 9197 return true; 9198 } 9199 if (context_->WasAllocatedUsingRobustnessExtension()) { 9200 GLenum status = GL_NO_ERROR; 9201 if (has_robustness_extension_) 9202 status = glGetGraphicsResetStatusARB(); 9203 if (status != GL_NO_ERROR) { 9204 // The graphics card was reset. Signal a lost context to the application. 9205 reset_status_ = status; 9206 reset_by_robustness_extension_ = true; 9207 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen") 9208 << " context lost via ARB/EXT_robustness. Reset status = " 9209 << GLES2Util::GetStringEnum(status); 9210 return true; 9211 } 9212 } 9213 return false; 9214 } 9215 9216 bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() { 9217 return WasContextLost() && reset_by_robustness_extension_; 9218 } 9219 9220 void GLES2DecoderImpl::LoseContext(uint32 reset_status) { 9221 // Only loses the context once. 9222 if (reset_status_ != GL_NO_ERROR) { 9223 return; 9224 } 9225 9226 // Marks this context as lost. 9227 reset_status_ = reset_status; 9228 current_decoder_error_ = error::kLostContext; 9229 } 9230 9231 error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM( 9232 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) { 9233 GLenum current = static_cast<GLenum>(c.current); 9234 GLenum other = static_cast<GLenum>(c.other); 9235 if (!validators_->reset_status.IsValid(current)) { 9236 LOCAL_SET_GL_ERROR_INVALID_ENUM( 9237 "glLoseContextCHROMIUM", current, "current"); 9238 } 9239 if (!validators_->reset_status.IsValid(other)) { 9240 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other"); 9241 } 9242 group_->LoseContexts(other); 9243 reset_status_ = current; 9244 current_decoder_error_ = error::kLostContext; 9245 return error::kLostContext; 9246 } 9247 9248 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM( 9249 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) { 9250 return error::kUnknownCommand; 9251 } 9252 9253 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM( 9254 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) { 9255 if (wait_sync_point_callback_.is_null()) 9256 return error::kNoError; 9257 9258 return wait_sync_point_callback_.Run(c.sync_point) ? 9259 error::kNoError : error::kDeferCommandUntilLater; 9260 } 9261 9262 bool GLES2DecoderImpl::GenQueriesEXTHelper( 9263 GLsizei n, const GLuint* client_ids) { 9264 for (GLsizei ii = 0; ii < n; ++ii) { 9265 if (query_manager_->GetQuery(client_ids[ii])) { 9266 return false; 9267 } 9268 } 9269 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT 9270 return true; 9271 } 9272 9273 void GLES2DecoderImpl::DeleteQueriesEXTHelper( 9274 GLsizei n, const GLuint* client_ids) { 9275 for (GLsizei ii = 0; ii < n; ++ii) { 9276 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]); 9277 if (query && !query->IsDeleted()) { 9278 if (query == state_.current_query.get()) { 9279 state_.current_query = NULL; 9280 } 9281 query->Destroy(true); 9282 query_manager_->RemoveQuery(client_ids[ii]); 9283 } 9284 } 9285 } 9286 9287 bool GLES2DecoderImpl::ProcessPendingQueries() { 9288 if (query_manager_.get() == NULL) { 9289 return false; 9290 } 9291 if (!query_manager_->ProcessPendingQueries()) { 9292 current_decoder_error_ = error::kOutOfBounds; 9293 } 9294 return query_manager_->HavePendingQueries(); 9295 } 9296 9297 // Note that if there are no pending readpixels right now, 9298 // this function will call the callback immediately. 9299 void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) { 9300 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) { 9301 pending_readpixel_fences_.back()->callbacks.push_back(callback); 9302 } else { 9303 callback.Run(); 9304 } 9305 } 9306 9307 void GLES2DecoderImpl::ProcessPendingReadPixels() { 9308 while (!pending_readpixel_fences_.empty() && 9309 pending_readpixel_fences_.front()->fence->HasCompleted()) { 9310 std::vector<base::Closure> callbacks = 9311 pending_readpixel_fences_.front()->callbacks; 9312 pending_readpixel_fences_.pop(); 9313 for (size_t i = 0; i < callbacks.size(); i++) { 9314 callbacks[i].Run(); 9315 } 9316 } 9317 } 9318 9319 bool GLES2DecoderImpl::HasMoreIdleWork() { 9320 return !pending_readpixel_fences_.empty() || 9321 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers(); 9322 } 9323 9324 void GLES2DecoderImpl::PerformIdleWork() { 9325 ProcessPendingReadPixels(); 9326 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers()) 9327 return; 9328 async_pixel_transfer_manager_->ProcessMorePendingTransfers(); 9329 ProcessFinishedAsyncTransfers(); 9330 } 9331 9332 error::Error GLES2DecoderImpl::HandleBeginQueryEXT( 9333 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) { 9334 GLenum target = static_cast<GLenum>(c.target); 9335 GLuint client_id = static_cast<GLuint>(c.id); 9336 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id); 9337 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); 9338 9339 switch (target) { 9340 case GL_COMMANDS_ISSUED_CHROMIUM: 9341 case GL_LATENCY_QUERY_CHROMIUM: 9342 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM: 9343 case GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM: 9344 case GL_GET_ERROR_QUERY_CHROMIUM: 9345 break; 9346 default: 9347 if (!features().occlusion_query_boolean) { 9348 LOCAL_SET_GL_ERROR( 9349 GL_INVALID_OPERATION, "glBeginQueryEXT", 9350 "not enabled for occlusion queries"); 9351 return error::kNoError; 9352 } 9353 break; 9354 } 9355 9356 // TODO(hubbe): Make it possible to have one query per type running at the 9357 // same time. 9358 if (state_.current_query.get()) { 9359 LOCAL_SET_GL_ERROR( 9360 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); 9361 return error::kNoError; 9362 } 9363 9364 if (client_id == 0) { 9365 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); 9366 return error::kNoError; 9367 } 9368 9369 QueryManager::Query* query = query_manager_->GetQuery(client_id); 9370 if (!query) { 9371 // TODO(gman): Decide if we need this check. 9372 // 9373 // Checks id was made by glGenQueries 9374 // 9375 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT 9376 // for all Query ids but from the POV of the command buffer service maybe 9377 // you don't. 9378 // 9379 // The client can enforce this. I don't think the service cares. 9380 // 9381 // IdAllocatorInterface* id_allocator = 9382 // group_->GetIdAllocator(id_namespaces::kQueries); 9383 // if (!id_allocator->InUse(client_id)) { 9384 // LOCAL_SET_GL_ERROR( 9385 // GL_INVALID_OPERATION, 9386 // "glBeginQueryEXT", "id not made by glGenQueriesEXT"); 9387 // return error::kNoError; 9388 // } 9389 query = query_manager_->CreateQuery( 9390 target, client_id, sync_shm_id, sync_shm_offset); 9391 } 9392 9393 if (query->target() != target) { 9394 LOCAL_SET_GL_ERROR( 9395 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match"); 9396 return error::kNoError; 9397 } else if (query->shm_id() != sync_shm_id || 9398 query->shm_offset() != sync_shm_offset) { 9399 DLOG(ERROR) << "Shared memory used by query not the same as before"; 9400 return error::kInvalidArguments; 9401 } 9402 9403 if (!query_manager_->BeginQuery(query)) { 9404 return error::kOutOfBounds; 9405 } 9406 9407 state_.current_query = query; 9408 return error::kNoError; 9409 } 9410 9411 error::Error GLES2DecoderImpl::HandleEndQueryEXT( 9412 uint32 immediate_data_size, const cmds::EndQueryEXT& c) { 9413 GLenum target = static_cast<GLenum>(c.target); 9414 uint32 submit_count = static_cast<GLuint>(c.submit_count); 9415 9416 if (!state_.current_query.get()) { 9417 LOCAL_SET_GL_ERROR( 9418 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query"); 9419 return error::kNoError; 9420 } 9421 if (state_.current_query->target() != target) { 9422 LOCAL_SET_GL_ERROR( 9423 GL_INVALID_OPERATION, 9424 "glEndQueryEXT", "target does not match active query"); 9425 return error::kNoError; 9426 } 9427 9428 if (!query_manager_->EndQuery(state_.current_query.get(), submit_count)) { 9429 return error::kOutOfBounds; 9430 } 9431 9432 query_manager_->ProcessPendingTransferQueries(); 9433 9434 state_.current_query = NULL; 9435 return error::kNoError; 9436 } 9437 9438 bool GLES2DecoderImpl::GenVertexArraysOESHelper( 9439 GLsizei n, const GLuint* client_ids) { 9440 for (GLsizei ii = 0; ii < n; ++ii) { 9441 if (GetVertexAttribManager(client_ids[ii])) { 9442 return false; 9443 } 9444 } 9445 9446 if (!features().native_vertex_array_object) { 9447 // Emulated VAO 9448 for (GLsizei ii = 0; ii < n; ++ii) { 9449 CreateVertexAttribManager(client_ids[ii], 0); 9450 } 9451 } else { 9452 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 9453 9454 glGenVertexArraysOES(n, service_ids.get()); 9455 for (GLsizei ii = 0; ii < n; ++ii) { 9456 CreateVertexAttribManager(client_ids[ii], service_ids[ii]); 9457 } 9458 } 9459 9460 return true; 9461 } 9462 9463 void GLES2DecoderImpl::DeleteVertexArraysOESHelper( 9464 GLsizei n, const GLuint* client_ids) { 9465 for (GLsizei ii = 0; ii < n; ++ii) { 9466 VertexAttribManager* vao = 9467 GetVertexAttribManager(client_ids[ii]); 9468 if (vao && !vao->IsDeleted()) { 9469 if (state_.vertex_attrib_manager.get() == vao) { 9470 state_.vertex_attrib_manager = default_vertex_attrib_manager_; 9471 } 9472 RemoveVertexAttribManager(client_ids[ii]); 9473 } 9474 } 9475 } 9476 9477 void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) { 9478 VertexAttribManager* vao = NULL; 9479 GLuint service_id = 0; 9480 if (client_id != 0) { 9481 vao = GetVertexAttribManager(client_id); 9482 if (!vao) { 9483 // Unlike most Bind* methods, the spec explicitly states that VertexArray 9484 // only allows names that have been previously generated. As such, we do 9485 // not generate new names here. 9486 LOCAL_SET_GL_ERROR( 9487 GL_INVALID_OPERATION, 9488 "glBindVertexArrayOES", "bad vertex array id."); 9489 current_decoder_error_ = error::kNoError; 9490 return; 9491 } else { 9492 service_id = vao->service_id(); 9493 } 9494 } else { 9495 vao = default_vertex_attrib_manager_.get(); 9496 } 9497 9498 // Only set the VAO state if it's changed 9499 if (state_.vertex_attrib_manager.get() != vao) { 9500 state_.vertex_attrib_manager = vao; 9501 if (!features().native_vertex_array_object) { 9502 EmulateVertexArrayState(); 9503 } else { 9504 glBindVertexArrayOES(service_id); 9505 } 9506 } 9507 } 9508 9509 // Used when OES_vertex_array_object isn't natively supported 9510 void GLES2DecoderImpl::EmulateVertexArrayState() { 9511 // Setup the Vertex attribute state 9512 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) { 9513 RestoreStateForAttrib(vv); 9514 } 9515 9516 // Setup the element buffer 9517 Buffer* element_array_buffer = 9518 state_.vertex_attrib_manager->element_array_buffer(); 9519 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 9520 element_array_buffer ? element_array_buffer->service_id() : 0); 9521 } 9522 9523 bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { 9524 const VertexAttribManager* vao = 9525 GetVertexAttribManager(client_id); 9526 return vao && vao->IsValid() && !vao->IsDeleted(); 9527 } 9528 9529 error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM( 9530 uint32 immediate_data_size, 9531 const cmds::CreateStreamTextureCHROMIUM& c) { 9532 if (!features().chromium_stream_texture) { 9533 LOCAL_SET_GL_ERROR( 9534 GL_INVALID_OPERATION, 9535 "glOpenStreamTextureCHROMIUM", "not supported."); 9536 return error::kNoError; 9537 } 9538 9539 uint32 client_id = c.client_id; 9540 typedef cmds::CreateStreamTextureCHROMIUM::Result Result; 9541 Result* result = GetSharedMemoryAs<Result*>( 9542 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 9543 9544 if (!result) 9545 return error::kOutOfBounds; 9546 *result = GL_ZERO; 9547 TextureRef* texture_ref = texture_manager()->GetTexture(client_id); 9548 if (!texture_ref) { 9549 LOCAL_SET_GL_ERROR( 9550 GL_INVALID_VALUE, 9551 "glCreateStreamTextureCHROMIUM", "bad texture id."); 9552 return error::kNoError; 9553 } 9554 9555 Texture* texture = texture_ref->texture(); 9556 if (texture->IsStreamTexture()) { 9557 LOCAL_SET_GL_ERROR( 9558 GL_INVALID_OPERATION, 9559 "glCreateStreamTextureCHROMIUM", "is already a stream texture."); 9560 return error::kNoError; 9561 } 9562 9563 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) { 9564 LOCAL_SET_GL_ERROR( 9565 GL_INVALID_OPERATION, 9566 "glCreateStreamTextureCHROMIUM", 9567 "is already bound to incompatible target."); 9568 return error::kNoError; 9569 } 9570 9571 if (!stream_texture_manager()) 9572 return error::kInvalidArguments; 9573 9574 GLuint object_id = stream_texture_manager()->CreateStreamTexture( 9575 texture->service_id(), client_id); 9576 9577 if (object_id) { 9578 texture_manager()->SetStreamTexture(texture_ref, true); 9579 } else { 9580 LOCAL_SET_GL_ERROR( 9581 GL_OUT_OF_MEMORY, 9582 "glCreateStreamTextureCHROMIUM", "failed to create platform texture."); 9583 } 9584 9585 *result = object_id; 9586 return error::kNoError; 9587 } 9588 9589 error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM( 9590 uint32 immediate_data_size, 9591 const cmds::DestroyStreamTextureCHROMIUM& c) { 9592 GLuint client_id = c.texture; 9593 TextureRef* texture_ref = texture_manager()->GetTexture(client_id); 9594 if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) { 9595 if (!stream_texture_manager()) 9596 return error::kInvalidArguments; 9597 9598 stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id()); 9599 texture_manager()->SetStreamTexture(texture_ref, false); 9600 } else { 9601 LOCAL_SET_GL_ERROR( 9602 GL_INVALID_VALUE, 9603 "glDestroyStreamTextureCHROMIUM", "bad texture id."); 9604 } 9605 9606 return error::kNoError; 9607 } 9608 9609 #if defined(OS_MACOSX) 9610 void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { 9611 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( 9612 texture_id); 9613 if (it != texture_to_io_surface_map_.end()) { 9614 // Found a previous IOSurface bound to this texture; release it. 9615 CFTypeRef surface = it->second; 9616 CFRelease(surface); 9617 texture_to_io_surface_map_.erase(it); 9618 } 9619 } 9620 #endif 9621 9622 void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM( 9623 GLenum target, GLsizei width, GLsizei height, 9624 GLuint io_surface_id, GLuint plane) { 9625 #if defined(OS_MACOSX) 9626 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { 9627 LOCAL_SET_GL_ERROR( 9628 GL_INVALID_OPERATION, 9629 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL."); 9630 return; 9631 } 9632 9633 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize(); 9634 if (!surface_support) { 9635 LOCAL_SET_GL_ERROR( 9636 GL_INVALID_OPERATION, 9637 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6."); 9638 return; 9639 } 9640 9641 if (target != GL_TEXTURE_RECTANGLE_ARB) { 9642 // This might be supported in the future, and if we could require 9643 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we 9644 // could delete a lot of code. For now, perform strict validation so we 9645 // know what's going on. 9646 LOCAL_SET_GL_ERROR( 9647 GL_INVALID_OPERATION, 9648 "glTexImageIOSurface2DCHROMIUM", 9649 "requires TEXTURE_RECTANGLE_ARB target"); 9650 return; 9651 } 9652 9653 // Default target might be conceptually valid, but disallow it to avoid 9654 // accidents. 9655 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target); 9656 if (!texture_ref) { 9657 LOCAL_SET_GL_ERROR( 9658 GL_INVALID_OPERATION, 9659 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound"); 9660 return; 9661 } 9662 9663 // Look up the new IOSurface. Note that because of asynchrony 9664 // between processes this might fail; during live resizing the 9665 // plugin process might allocate and release an IOSurface before 9666 // this process gets a chance to look it up. Hold on to any old 9667 // IOSurface in this case. 9668 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id); 9669 if (!surface) { 9670 LOCAL_SET_GL_ERROR( 9671 GL_INVALID_OPERATION, 9672 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID"); 9673 return; 9674 } 9675 9676 // Release any IOSurface previously bound to this texture. 9677 ReleaseIOSurfaceForTexture(texture_ref->service_id()); 9678 9679 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails. 9680 texture_to_io_surface_map_.insert( 9681 std::make_pair(texture_ref->service_id(), surface)); 9682 9683 CGLContextObj context = 9684 static_cast<CGLContextObj>(context_->GetHandle()); 9685 9686 CGLError err = surface_support->CGLTexImageIOSurface2D( 9687 context, 9688 target, 9689 GL_RGBA, 9690 width, 9691 height, 9692 GL_BGRA, 9693 GL_UNSIGNED_INT_8_8_8_8_REV, 9694 surface, 9695 plane); 9696 9697 if (err != kCGLNoError) { 9698 LOCAL_SET_GL_ERROR( 9699 GL_INVALID_OPERATION, 9700 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D"); 9701 return; 9702 } 9703 9704 texture_manager()->SetLevelInfo( 9705 texture_ref, target, 0, GL_RGBA, width, height, 1, 0, 9706 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true); 9707 9708 #else 9709 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 9710 "glTexImageIOSurface2DCHROMIUM", "not supported."); 9711 #endif 9712 } 9713 9714 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { 9715 switch (internalformat) { 9716 case GL_RGB565: 9717 return GL_RGB; 9718 case GL_RGBA4: 9719 return GL_RGBA; 9720 case GL_RGB5_A1: 9721 return GL_RGBA; 9722 case GL_RGB8_OES: 9723 return GL_RGB; 9724 case GL_RGBA8_OES: 9725 return GL_RGBA; 9726 case GL_LUMINANCE8_ALPHA8_EXT: 9727 return GL_LUMINANCE_ALPHA; 9728 case GL_LUMINANCE8_EXT: 9729 return GL_LUMINANCE; 9730 case GL_ALPHA8_EXT: 9731 return GL_ALPHA; 9732 case GL_RGBA32F_EXT: 9733 return GL_RGBA; 9734 case GL_RGB32F_EXT: 9735 return GL_RGB; 9736 case GL_ALPHA32F_EXT: 9737 return GL_ALPHA; 9738 case GL_LUMINANCE32F_EXT: 9739 return GL_LUMINANCE; 9740 case GL_LUMINANCE_ALPHA32F_EXT: 9741 return GL_LUMINANCE_ALPHA; 9742 case GL_RGBA16F_EXT: 9743 return GL_RGBA; 9744 case GL_RGB16F_EXT: 9745 return GL_RGB; 9746 case GL_ALPHA16F_EXT: 9747 return GL_ALPHA; 9748 case GL_LUMINANCE16F_EXT: 9749 return GL_LUMINANCE; 9750 case GL_LUMINANCE_ALPHA16F_EXT: 9751 return GL_LUMINANCE_ALPHA; 9752 case GL_BGRA8_EXT: 9753 return GL_BGRA_EXT; 9754 default: 9755 return GL_NONE; 9756 } 9757 } 9758 9759 void GLES2DecoderImpl::DoCopyTextureCHROMIUM( 9760 GLenum target, GLuint source_id, GLuint dest_id, GLint level, 9761 GLenum internal_format, GLenum dest_type) { 9762 TextureRef* dest_texture_ref = GetTexture(dest_id); 9763 TextureRef* source_texture_ref = GetTexture(source_id); 9764 9765 if (!source_texture_ref || !dest_texture_ref) { 9766 LOCAL_SET_GL_ERROR( 9767 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id"); 9768 return; 9769 } 9770 9771 if (GL_TEXTURE_2D != target) { 9772 LOCAL_SET_GL_ERROR( 9773 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target"); 9774 return; 9775 } 9776 9777 Texture* source_texture = source_texture_ref->texture(); 9778 Texture* dest_texture = dest_texture_ref->texture(); 9779 if (dest_texture->target() != GL_TEXTURE_2D || 9780 (source_texture->target() != GL_TEXTURE_2D && 9781 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) { 9782 LOCAL_SET_GL_ERROR( 9783 GL_INVALID_VALUE, 9784 "glCopyTextureCHROMIUM", "invalid texture target binding"); 9785 return; 9786 } 9787 9788 int source_width, source_height, dest_width, dest_height; 9789 9790 if (source_texture->target() == GL_TEXTURE_2D) { 9791 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, 9792 &source_height)) { 9793 LOCAL_SET_GL_ERROR( 9794 GL_INVALID_VALUE, 9795 "glCopyTextureChromium", "source texture has no level 0"); 9796 return; 9797 } 9798 9799 // Check that this type of texture is allowed. 9800 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width, 9801 source_height, 1)) { 9802 LOCAL_SET_GL_ERROR( 9803 GL_INVALID_VALUE, 9804 "glCopyTextureCHROMIUM", "Bad dimensions"); 9805 return; 9806 } 9807 } 9808 9809 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { 9810 DCHECK(stream_texture_manager()); 9811 StreamTexture* stream_tex = 9812 stream_texture_manager()->LookupStreamTexture( 9813 source_texture->service_id()); 9814 if (!stream_tex) { 9815 LOCAL_SET_GL_ERROR( 9816 GL_INVALID_VALUE, 9817 "glCopyTextureChromium", "Stream texture lookup failed"); 9818 return; 9819 } 9820 gfx::Size size = stream_tex->GetSize(); 9821 source_width = size.width(); 9822 source_height = size.height(); 9823 if (source_width <= 0 || source_height <= 0) { 9824 LOCAL_SET_GL_ERROR( 9825 GL_INVALID_VALUE, 9826 "glCopyTextureChromium", "invalid streamtexture size"); 9827 return; 9828 } 9829 } 9830 9831 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is 9832 // needed because it takes 10s of milliseconds to initialize. 9833 if (!copy_texture_CHROMIUM_.get()) { 9834 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); 9835 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); 9836 copy_texture_CHROMIUM_->Initialize(this); 9837 RestoreCurrentFramebufferBindings(); 9838 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR) 9839 return; 9840 } 9841 9842 GLenum dest_type_previous; 9843 GLenum dest_internal_format; 9844 bool dest_level_defined = dest_texture->GetLevelSize( 9845 GL_TEXTURE_2D, level, &dest_width, &dest_height); 9846 9847 if (dest_level_defined) { 9848 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous, 9849 &dest_internal_format); 9850 } 9851 9852 // Resize the destination texture to the dimensions of the source texture. 9853 if (!dest_level_defined || dest_width != source_width || 9854 dest_height != source_height || 9855 dest_internal_format != internal_format || 9856 dest_type_previous != dest_type) { 9857 // Ensure that the glTexImage2D succeeds. 9858 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); 9859 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); 9860 glTexImage2D( 9861 GL_TEXTURE_2D, level, internal_format, source_width, source_height, 9862 0, internal_format, dest_type, NULL); 9863 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); 9864 if (error != GL_NO_ERROR) { 9865 RestoreCurrentTexture2DBindings(); 9866 return; 9867 } 9868 9869 texture_manager()->SetLevelInfo( 9870 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width, 9871 source_height, 1, 0, internal_format, dest_type, true); 9872 } else { 9873 texture_manager()->SetLevelCleared( 9874 dest_texture_ref, GL_TEXTURE_2D, level, true); 9875 } 9876 9877 DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); 9878 9879 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix 9880 // before presenting. 9881 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { 9882 // TODO(hkuang): get the StreamTexture transform matrix in GPU process 9883 // instead of using default matrix crbug.com/226218. 9884 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 9885 0.0f, 1.0f, 0.0f, 0.0f, 9886 0.0f, 0.0f, 1.0f, 0.0f, 9887 0.0f, 0.0f, 0.0f, 1.0f}; 9888 copy_texture_CHROMIUM_->DoCopyTextureWithTransform( 9889 this, 9890 source_texture->target(), 9891 dest_texture->target(), 9892 source_texture->service_id(), 9893 dest_texture->service_id(), level, 9894 source_width, source_height, 9895 unpack_flip_y_, 9896 unpack_premultiply_alpha_, 9897 unpack_unpremultiply_alpha_, 9898 default_matrix); 9899 } else { 9900 copy_texture_CHROMIUM_->DoCopyTexture( 9901 this, 9902 source_texture->target(), 9903 dest_texture->target(), 9904 source_texture->service_id(), 9905 dest_texture->service_id(), level, 9906 source_width, source_height, 9907 unpack_flip_y_, 9908 unpack_premultiply_alpha_, 9909 unpack_unpremultiply_alpha_); 9910 } 9911 9912 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); 9913 } 9914 9915 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { 9916 switch (internalformat) { 9917 case GL_RGB565: 9918 return GL_UNSIGNED_SHORT_5_6_5; 9919 case GL_RGBA4: 9920 return GL_UNSIGNED_SHORT_4_4_4_4; 9921 case GL_RGB5_A1: 9922 return GL_UNSIGNED_SHORT_5_5_5_1; 9923 case GL_RGB8_OES: 9924 return GL_UNSIGNED_BYTE; 9925 case GL_RGBA8_OES: 9926 return GL_UNSIGNED_BYTE; 9927 case GL_LUMINANCE8_ALPHA8_EXT: 9928 return GL_UNSIGNED_BYTE; 9929 case GL_LUMINANCE8_EXT: 9930 return GL_UNSIGNED_BYTE; 9931 case GL_ALPHA8_EXT: 9932 return GL_UNSIGNED_BYTE; 9933 case GL_RGBA32F_EXT: 9934 return GL_FLOAT; 9935 case GL_RGB32F_EXT: 9936 return GL_FLOAT; 9937 case GL_ALPHA32F_EXT: 9938 return GL_FLOAT; 9939 case GL_LUMINANCE32F_EXT: 9940 return GL_FLOAT; 9941 case GL_LUMINANCE_ALPHA32F_EXT: 9942 return GL_FLOAT; 9943 case GL_RGBA16F_EXT: 9944 return GL_HALF_FLOAT_OES; 9945 case GL_RGB16F_EXT: 9946 return GL_HALF_FLOAT_OES; 9947 case GL_ALPHA16F_EXT: 9948 return GL_HALF_FLOAT_OES; 9949 case GL_LUMINANCE16F_EXT: 9950 return GL_HALF_FLOAT_OES; 9951 case GL_LUMINANCE_ALPHA16F_EXT: 9952 return GL_HALF_FLOAT_OES; 9953 case GL_BGRA8_EXT: 9954 return GL_UNSIGNED_BYTE; 9955 default: 9956 return GL_NONE; 9957 } 9958 } 9959 9960 void GLES2DecoderImpl::DoTexStorage2DEXT( 9961 GLenum target, 9962 GLint levels, 9963 GLenum internal_format, 9964 GLsizei width, 9965 GLsizei height) { 9966 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT"); 9967 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || 9968 TextureManager::ComputeMipMapCount(width, height, 1) < levels) { 9969 LOCAL_SET_GL_ERROR( 9970 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range"); 9971 return; 9972 } 9973 TextureRef* texture_ref = GetTextureInfoForTarget(target); 9974 if (!texture_ref) { 9975 LOCAL_SET_GL_ERROR( 9976 GL_INVALID_OPERATION, 9977 "glTexStorage2DEXT", "unknown texture for target"); 9978 return; 9979 } 9980 Texture* texture = texture_ref->texture(); 9981 if (texture->IsAttachedToFramebuffer()) { 9982 clear_state_dirty_ = true; 9983 } 9984 if (texture->IsImmutable()) { 9985 LOCAL_SET_GL_ERROR( 9986 GL_INVALID_OPERATION, 9987 "glTexStorage2DEXT", "texture is immutable"); 9988 return; 9989 } 9990 9991 GLenum format = ExtractFormatFromStorageFormat(internal_format); 9992 GLenum type = ExtractTypeFromStorageFormat(internal_format); 9993 9994 { 9995 GLsizei level_width = width; 9996 GLsizei level_height = height; 9997 uint32 estimated_size = 0; 9998 for (int ii = 0; ii < levels; ++ii) { 9999 uint32 level_size = 0; 10000 if (!GLES2Util::ComputeImageDataSizes( 10001 level_width, level_height, format, type, state_.unpack_alignment, 10002 &estimated_size, NULL, NULL) || 10003 !SafeAddUint32(estimated_size, level_size, &estimated_size)) { 10004 LOCAL_SET_GL_ERROR( 10005 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large"); 10006 return; 10007 } 10008 level_width = std::max(1, level_width >> 1); 10009 level_height = std::max(1, level_height >> 1); 10010 } 10011 if (!EnsureGPUMemoryAvailable(estimated_size)) { 10012 LOCAL_SET_GL_ERROR( 10013 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory"); 10014 return; 10015 } 10016 } 10017 10018 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT"); 10019 glTexStorage2DEXT(target, levels, internal_format, width, height); 10020 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT"); 10021 if (error == GL_NO_ERROR) { 10022 GLsizei level_width = width; 10023 GLsizei level_height = height; 10024 for (int ii = 0; ii < levels; ++ii) { 10025 texture_manager()->SetLevelInfo( 10026 texture_ref, target, ii, format, 10027 level_width, level_height, 1, 0, format, type, false); 10028 level_width = std::max(1, level_width >> 1); 10029 level_height = std::max(1, level_height >> 1); 10030 } 10031 texture->SetImmutable(true); 10032 } 10033 } 10034 10035 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( 10036 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) { 10037 MailboxName name; 10038 mailbox_manager()->GenerateMailboxName(&name); 10039 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 10040 Bucket* bucket = CreateBucket(bucket_id); 10041 10042 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM); 10043 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM); 10044 10045 return error::kNoError; 10046 } 10047 10048 void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target, 10049 const GLbyte* mailbox) { 10050 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM", 10051 "context", logger_.GetLogPrefix(), 10052 "mailbox[0]", static_cast<unsigned char>(mailbox[0])); 10053 10054 TextureRef* texture_ref = GetTextureInfoForTarget(target); 10055 if (!texture_ref) { 10056 LOCAL_SET_GL_ERROR( 10057 GL_INVALID_OPERATION, 10058 "glProduceTextureCHROMIUM", "unknown texture for target"); 10059 return; 10060 } 10061 10062 Texture* produced = texture_manager()->Produce(texture_ref); 10063 if (!produced) { 10064 LOCAL_SET_GL_ERROR( 10065 GL_INVALID_OPERATION, 10066 "glProduceTextureCHROMIUM", "invalid texture"); 10067 return; 10068 } 10069 10070 if (!group_->mailbox_manager()->ProduceTexture( 10071 target, 10072 *reinterpret_cast<const MailboxName*>(mailbox), 10073 produced)) { 10074 LOCAL_SET_GL_ERROR( 10075 GL_INVALID_OPERATION, 10076 "glProduceTextureCHROMIUM", "invalid mailbox name"); 10077 return; 10078 } 10079 } 10080 10081 void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target, 10082 const GLbyte* mailbox) { 10083 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM", 10084 "context", logger_.GetLogPrefix(), 10085 "mailbox[0]", static_cast<unsigned char>(mailbox[0])); 10086 10087 scoped_refptr<TextureRef> texture_ref = 10088 GetTextureInfoForTargetUnlessDefault(target); 10089 if (!texture_ref.get()) { 10090 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 10091 "glConsumeTextureCHROMIUM", 10092 "unknown texture for target"); 10093 return; 10094 } 10095 GLuint client_id = texture_ref->client_id(); 10096 if (!client_id) { 10097 LOCAL_SET_GL_ERROR( 10098 GL_INVALID_OPERATION, 10099 "glConsumeTextureCHROMIUM", "unknown texture for target"); 10100 return; 10101 } 10102 Texture* texture = 10103 group_->mailbox_manager()->ConsumeTexture( 10104 target, 10105 *reinterpret_cast<const MailboxName*>(mailbox)); 10106 if (!texture) { 10107 LOCAL_SET_GL_ERROR( 10108 GL_INVALID_OPERATION, 10109 "glConsumeTextureCHROMIUM", "invalid mailbox name"); 10110 return; 10111 } 10112 if (texture->target() != target) { 10113 LOCAL_SET_GL_ERROR( 10114 GL_INVALID_OPERATION, 10115 "glConsumeTextureCHROMIUM", "invalid target"); 10116 return; 10117 } 10118 10119 DeleteTexturesHelper(1, &client_id); 10120 texture_ref = texture_manager()->Consume(client_id, texture); 10121 glBindTexture(target, texture_ref->service_id()); 10122 10123 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 10124 unit.bind_target = target; 10125 switch (target) { 10126 case GL_TEXTURE_2D: 10127 unit.bound_texture_2d = texture_ref; 10128 break; 10129 case GL_TEXTURE_CUBE_MAP: 10130 unit.bound_texture_cube_map = texture_ref; 10131 break; 10132 case GL_TEXTURE_EXTERNAL_OES: 10133 unit.bound_texture_external_oes = texture_ref; 10134 break; 10135 case GL_TEXTURE_RECTANGLE_ARB: 10136 unit.bound_texture_rectangle_arb = texture_ref; 10137 break; 10138 default: 10139 NOTREACHED(); // Validation should prevent us getting here. 10140 break; 10141 } 10142 } 10143 10144 void GLES2DecoderImpl::DoInsertEventMarkerEXT( 10145 GLsizei length, const GLchar* marker) { 10146 if (!marker) { 10147 marker = ""; 10148 } 10149 debug_marker_manager_.SetMarker( 10150 length ? std::string(marker, length) : std::string(marker)); 10151 } 10152 10153 void GLES2DecoderImpl::DoPushGroupMarkerEXT( 10154 GLsizei length, const GLchar* marker) { 10155 if (!marker) { 10156 marker = ""; 10157 } 10158 debug_marker_manager_.PushGroup( 10159 length ? std::string(marker, length) : std::string(marker)); 10160 } 10161 10162 void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) { 10163 debug_marker_manager_.PopGroup(); 10164 } 10165 10166 void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( 10167 GLenum target, GLint image_id) { 10168 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM"); 10169 if (target != GL_TEXTURE_2D) { 10170 // This might be supported in the future. 10171 LOCAL_SET_GL_ERROR( 10172 GL_INVALID_OPERATION, 10173 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target"); 10174 return; 10175 } 10176 10177 // Default target might be conceptually valid, but disallow it to avoid 10178 // accidents. 10179 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target); 10180 if (!texture_ref) { 10181 LOCAL_SET_GL_ERROR( 10182 GL_INVALID_OPERATION, 10183 "glBindTexImage2DCHROMIUM", "no texture bound"); 10184 return; 10185 } 10186 10187 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id); 10188 if (!gl_image) { 10189 LOCAL_SET_GL_ERROR( 10190 GL_INVALID_OPERATION, 10191 "glBindTexImage2DCHROMIUM", "no image found with the given ID"); 10192 return; 10193 } 10194 10195 { 10196 ScopedGLErrorSuppressor suppressor( 10197 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this); 10198 if (!gl_image->BindTexImage()) { 10199 LOCAL_SET_GL_ERROR( 10200 GL_INVALID_OPERATION, 10201 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID"); 10202 return; 10203 } 10204 } 10205 10206 gfx::Size size = gl_image->GetSize(); 10207 texture_manager()->SetLevelInfo( 10208 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0, 10209 GL_RGBA, GL_UNSIGNED_BYTE, true); 10210 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image); 10211 } 10212 10213 void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( 10214 GLenum target, GLint image_id) { 10215 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); 10216 if (target != GL_TEXTURE_2D) { 10217 // This might be supported in the future. 10218 LOCAL_SET_GL_ERROR( 10219 GL_INVALID_OPERATION, 10220 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target"); 10221 return; 10222 } 10223 10224 // Default target might be conceptually valid, but disallow it to avoid 10225 // accidents. 10226 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target); 10227 if (!texture_ref) { 10228 LOCAL_SET_GL_ERROR( 10229 GL_INVALID_OPERATION, 10230 "glReleaseTexImage2DCHROMIUM", "no texture bound"); 10231 return; 10232 } 10233 10234 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id); 10235 if (!gl_image) { 10236 LOCAL_SET_GL_ERROR( 10237 GL_INVALID_OPERATION, 10238 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID"); 10239 return; 10240 } 10241 10242 // Do nothing when image is not currently bound. 10243 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image) 10244 return; 10245 10246 { 10247 ScopedGLErrorSuppressor suppressor( 10248 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this); 10249 gl_image->ReleaseTexImage(); 10250 } 10251 10252 texture_manager()->SetLevelInfo( 10253 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0, 10254 GL_RGBA, GL_UNSIGNED_BYTE, false); 10255 } 10256 10257 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM( 10258 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) { 10259 Bucket* bucket = GetBucket(c.bucket_id); 10260 if (!bucket || bucket->size() == 0) { 10261 return error::kInvalidArguments; 10262 } 10263 std::string command_name; 10264 if (!bucket->GetAsString(&command_name)) { 10265 return error::kInvalidArguments; 10266 } 10267 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this); 10268 if (!gpu_tracer_->Begin(command_name)) { 10269 LOCAL_SET_GL_ERROR( 10270 GL_INVALID_OPERATION, 10271 "glTraceBeginCHROMIUM", "unable to create begin trace"); 10272 return error::kNoError; 10273 } 10274 return error::kNoError; 10275 } 10276 10277 void GLES2DecoderImpl::DoTraceEndCHROMIUM() { 10278 if (gpu_tracer_->CurrentName().empty()) { 10279 LOCAL_SET_GL_ERROR( 10280 GL_INVALID_OPERATION, 10281 "glTraceEndCHROMIUM", "no trace begin found"); 10282 return; 10283 } 10284 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this); 10285 gpu_tracer_->End(); 10286 } 10287 10288 void GLES2DecoderImpl::DoDrawBuffersEXT( 10289 GLsizei count, const GLenum* bufs) { 10290 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) { 10291 LOCAL_SET_GL_ERROR( 10292 GL_INVALID_VALUE, 10293 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT"); 10294 return; 10295 } 10296 10297 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 10298 if (framebuffer) { 10299 for (GLsizei i = 0; i < count; ++i) { 10300 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) && 10301 bufs[i] != GL_NONE) { 10302 LOCAL_SET_GL_ERROR( 10303 GL_INVALID_OPERATION, 10304 "glDrawBuffersEXT", 10305 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT"); 10306 return; 10307 } 10308 } 10309 glDrawBuffersARB(count, bufs); 10310 framebuffer->SetDrawBuffers(count, bufs); 10311 } else { // backbuffer 10312 if (count > 1 || 10313 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) { 10314 LOCAL_SET_GL_ERROR( 10315 GL_INVALID_OPERATION, 10316 "glDrawBuffersEXT", 10317 "more than one buffer or bufs not GL_NONE or GL_BACK"); 10318 return; 10319 } 10320 GLenum mapped_buf = bufs[0]; 10321 if (GetBackbufferServiceId() != 0 && // emulated backbuffer 10322 bufs[0] == GL_BACK) { 10323 mapped_buf = GL_COLOR_ATTACHMENT0; 10324 } 10325 glDrawBuffersARB(count, &mapped_buf); 10326 group_->set_draw_buffer(bufs[0]); 10327 } 10328 } 10329 10330 bool GLES2DecoderImpl::ValidateAsyncTransfer( 10331 const char* function_name, 10332 TextureRef* texture_ref, 10333 GLenum target, 10334 GLint level, 10335 const void * data) { 10336 // We only support async uploads to 2D textures for now. 10337 if (GL_TEXTURE_2D != target) { 10338 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target"); 10339 return false; 10340 } 10341 // We only support uploads to level zero for now. 10342 if (level != 0) { 10343 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0"); 10344 return false; 10345 } 10346 // A transfer buffer must be bound, even for asyncTexImage2D. 10347 if (data == NULL) { 10348 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0"); 10349 return false; 10350 } 10351 // We only support one async transfer in progress. 10352 if (!texture_ref || 10353 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) { 10354 LOCAL_SET_GL_ERROR( 10355 GL_INVALID_OPERATION, 10356 function_name, "transfer already in progress"); 10357 return false; 10358 } 10359 return true; 10360 } 10361 10362 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM( 10363 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) { 10364 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM"); 10365 GLenum target = static_cast<GLenum>(c.target); 10366 GLint level = static_cast<GLint>(c.level); 10367 GLint internal_format = static_cast<GLint>(c.internalformat); 10368 GLsizei width = static_cast<GLsizei>(c.width); 10369 GLsizei height = static_cast<GLsizei>(c.height); 10370 GLint border = static_cast<GLint>(c.border); 10371 GLenum format = static_cast<GLenum>(c.format); 10372 GLenum type = static_cast<GLenum>(c.type); 10373 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 10374 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 10375 uint32 pixels_size; 10376 10377 // TODO(epenner): Move this and copies of this memory validation 10378 // into ValidateTexImage2D step. 10379 if (!GLES2Util::ComputeImageDataSizes( 10380 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 10381 NULL)) { 10382 return error::kOutOfBounds; 10383 } 10384 const void* pixels = NULL; 10385 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 10386 pixels = GetSharedMemoryAs<const void*>( 10387 pixels_shm_id, pixels_shm_offset, pixels_size); 10388 if (!pixels) { 10389 return error::kOutOfBounds; 10390 } 10391 } 10392 10393 // All the normal glTexSubImage2D validation. 10394 if (!ValidateTexImage2D( 10395 "glAsyncTexImage2DCHROMIUM", target, level, internal_format, 10396 width, height, border, format, type, pixels, pixels_size)) { 10397 return error::kNoError; 10398 } 10399 10400 // Extra async validation. 10401 TextureRef* texture_ref = GetTextureInfoForTarget(target); 10402 Texture* texture = texture_ref->texture(); 10403 if (!ValidateAsyncTransfer( 10404 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels)) 10405 return error::kNoError; 10406 10407 // Don't allow async redefinition of a textures. 10408 if (texture->IsDefined()) { 10409 LOCAL_SET_GL_ERROR( 10410 GL_INVALID_OPERATION, 10411 "glAsyncTexImage2DCHROMIUM", "already defined"); 10412 return error::kNoError; 10413 } 10414 10415 if (!EnsureGPUMemoryAvailable(pixels_size)) { 10416 LOCAL_SET_GL_ERROR( 10417 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory"); 10418 return error::kNoError; 10419 } 10420 10421 // We know the memory/size is safe, so get the real shared memory since 10422 // it might need to be duped to prevent use-after-free of the memory. 10423 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); 10424 base::SharedMemory* shared_memory = buffer.shared_memory; 10425 uint32 shm_size = buffer.size; 10426 uint32 shm_data_offset = c.pixels_shm_offset; 10427 uint32 shm_data_size = pixels_size; 10428 10429 // Setup the parameters. 10430 AsyncTexImage2DParams tex_params = { 10431 target, level, static_cast<GLenum>(internal_format), 10432 width, height, border, format, type}; 10433 AsyncMemoryParams mem_params = { 10434 shared_memory, shm_size, shm_data_offset, shm_data_size}; 10435 10436 // Set up the async state if needed, and make the texture 10437 // immutable so the async state stays valid. The level info 10438 // is set up lazily when the transfer completes. 10439 AsyncPixelTransferDelegate* delegate = 10440 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref, 10441 tex_params); 10442 texture->SetImmutable(true); 10443 10444 delegate->AsyncTexImage2D( 10445 tex_params, 10446 mem_params, 10447 base::Bind(&TextureManager::SetLevelInfoFromParams, 10448 // The callback is only invoked if the transfer delegate still 10449 // exists, which implies through manager->texture_ref->state 10450 // ownership that both of these pointers are valid. 10451 base::Unretained(texture_manager()), 10452 base::Unretained(texture_ref), 10453 tex_params)); 10454 return error::kNoError; 10455 } 10456 10457 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM( 10458 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) { 10459 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM"); 10460 GLenum target = static_cast<GLenum>(c.target); 10461 GLint level = static_cast<GLint>(c.level); 10462 GLint xoffset = static_cast<GLint>(c.xoffset); 10463 GLint yoffset = static_cast<GLint>(c.yoffset); 10464 GLsizei width = static_cast<GLsizei>(c.width); 10465 GLsizei height = static_cast<GLsizei>(c.height); 10466 GLenum format = static_cast<GLenum>(c.format); 10467 GLenum type = static_cast<GLenum>(c.type); 10468 10469 // TODO(epenner): Move this and copies of this memory validation 10470 // into ValidateTexSubImage2D step. 10471 uint32 data_size; 10472 if (!GLES2Util::ComputeImageDataSizes( 10473 width, height, format, type, state_.unpack_alignment, &data_size, 10474 NULL, NULL)) { 10475 return error::kOutOfBounds; 10476 } 10477 const void* pixels = GetSharedMemoryAs<const void*>( 10478 c.data_shm_id, c.data_shm_offset, data_size); 10479 10480 // All the normal glTexSubImage2D validation. 10481 error::Error error = error::kNoError; 10482 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM", 10483 target, level, xoffset, yoffset, width, height, format, type, pixels)) { 10484 return error; 10485 } 10486 10487 // Extra async validation. 10488 TextureRef* texture_ref = GetTextureInfoForTarget(target); 10489 Texture* texture = texture_ref->texture(); 10490 if (!ValidateAsyncTransfer( 10491 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels)) 10492 return error::kNoError; 10493 10494 // Guarantee async textures are always 'cleared' as follows: 10495 // - AsyncTexImage2D can not redefine an existing texture 10496 // - AsyncTexImage2D must initialize the entire image via non-null buffer. 10497 // - AsyncTexSubImage2D clears synchronously if not already cleared. 10498 // - Textures become immutable after an async call. 10499 // This way we know in all cases that an async texture is always clear. 10500 if (!texture->SafeToRenderFrom()) { 10501 if (!texture_manager()->ClearTextureLevel(this, texture_ref, 10502 target, level)) { 10503 LOCAL_SET_GL_ERROR( 10504 GL_OUT_OF_MEMORY, 10505 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big"); 10506 return error::kNoError; 10507 } 10508 } 10509 10510 // We know the memory/size is safe, so get the real shared memory since 10511 // it might need to be duped to prevent use-after-free of the memory. 10512 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id); 10513 base::SharedMemory* shared_memory = buffer.shared_memory; 10514 uint32 shm_size = buffer.size; 10515 uint32 shm_data_offset = c.data_shm_offset; 10516 uint32 shm_data_size = data_size; 10517 10518 // Setup the parameters. 10519 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset, 10520 width, height, format, type}; 10521 AsyncMemoryParams mem_params = {shared_memory, shm_size, 10522 shm_data_offset, shm_data_size}; 10523 AsyncPixelTransferDelegate* delegate = 10524 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref); 10525 if (!delegate) { 10526 // TODO(epenner): We may want to enforce exclusive use 10527 // of async APIs in which case this should become an error, 10528 // (the texture should have been async defined). 10529 AsyncTexImage2DParams define_params = {target, level, 10530 0, 0, 0, 0, 0, 0}; 10531 texture->GetLevelSize(target, level, &define_params.width, 10532 &define_params.height); 10533 texture->GetLevelType(target, level, &define_params.type, 10534 &define_params.internal_format); 10535 // Set up the async state if needed, and make the texture 10536 // immutable so the async state stays valid. 10537 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate( 10538 texture_ref, define_params); 10539 texture->SetImmutable(true); 10540 } 10541 10542 delegate->AsyncTexSubImage2D(tex_params, mem_params); 10543 return error::kNoError; 10544 } 10545 10546 error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM( 10547 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) { 10548 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM"); 10549 GLenum target = static_cast<GLenum>(c.target); 10550 10551 if (GL_TEXTURE_2D != target) { 10552 LOCAL_SET_GL_ERROR( 10553 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target"); 10554 return error::kNoError; 10555 } 10556 TextureRef* texture_ref = GetTextureInfoForTarget(target); 10557 if (!texture_ref) { 10558 LOCAL_SET_GL_ERROR( 10559 GL_INVALID_OPERATION, 10560 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture"); 10561 return error::kNoError; 10562 } 10563 AsyncPixelTransferDelegate* delegate = 10564 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref); 10565 if (!delegate) { 10566 LOCAL_SET_GL_ERROR( 10567 GL_INVALID_OPERATION, 10568 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started"); 10569 return error::kNoError; 10570 } 10571 delegate->WaitForTransferCompletion(); 10572 ProcessFinishedAsyncTransfers(); 10573 return error::kNoError; 10574 } 10575 10576 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( 10577 TextureRef* texture_ref) { 10578 Texture* texture = texture_ref->texture(); 10579 DoDidUseTexImageIfNeeded(texture, texture->target()); 10580 } 10581 10582 // Include the auto-generated part of this file. We split this because it means 10583 // we can easily edit the non-auto generated parts right here in this file 10584 // instead of having to edit some template or the code generator. 10585 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 10586 10587 } // namespace gles2 10588 } // namespace gpu 10589