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/bind.h" 18 #include "base/callback_helpers.h" 19 #include "base/command_line.h" 20 #include "base/debug/trace_event.h" 21 #include "base/debug/trace_event_synthetic_delay.h" 22 #include "base/memory/scoped_ptr.h" 23 #include "base/numerics/safe_math.h" 24 #include "base/strings/string_number_conversions.h" 25 #include "base/strings/string_split.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_state_tracer.h" 46 #include "gpu/command_buffer/service/gpu_switches.h" 47 #include "gpu/command_buffer/service/gpu_tracer.h" 48 #include "gpu/command_buffer/service/image_manager.h" 49 #include "gpu/command_buffer/service/mailbox_manager.h" 50 #include "gpu/command_buffer/service/memory_tracking.h" 51 #include "gpu/command_buffer/service/program_manager.h" 52 #include "gpu/command_buffer/service/query_manager.h" 53 #include "gpu/command_buffer/service/renderbuffer_manager.h" 54 #include "gpu/command_buffer/service/shader_manager.h" 55 #include "gpu/command_buffer/service/shader_translator.h" 56 #include "gpu/command_buffer/service/shader_translator_cache.h" 57 #include "gpu/command_buffer/service/texture_manager.h" 58 #include "gpu/command_buffer/service/vertex_array_manager.h" 59 #include "gpu/command_buffer/service/vertex_attrib_manager.h" 60 #include "third_party/smhasher/src/City.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 <IOSurface/IOSurfaceAPI.h> 69 // Note that this must be included after gl_bindings.h to avoid conflicts. 70 #include <OpenGL/CGLIOSurface.h> 71 #endif 72 73 #if defined(OS_WIN) 74 #include "base/win/win_util.h" 75 #endif 76 77 namespace gpu { 78 namespace gles2 { 79 80 namespace { 81 82 static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives"; 83 static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth"; 84 static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers"; 85 static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod"; 86 87 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108 88 khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) { 89 return static_cast<khronos_uint64_t>( 90 CityHash64(name, static_cast<size_t>(len))); 91 } 92 #endif 93 94 static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin, 95 GLint rangeMax, 96 GLint precision) { 97 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16); 98 } 99 100 static void GetShaderPrecisionFormatImpl(GLenum shader_type, 101 GLenum precision_type, 102 GLint *range, GLint *precision) { 103 switch (precision_type) { 104 case GL_LOW_INT: 105 case GL_MEDIUM_INT: 106 case GL_HIGH_INT: 107 // These values are for a 32-bit twos-complement integer format. 108 range[0] = 31; 109 range[1] = 30; 110 *precision = 0; 111 break; 112 case GL_LOW_FLOAT: 113 case GL_MEDIUM_FLOAT: 114 case GL_HIGH_FLOAT: 115 // These values are for an IEEE single-precision floating-point format. 116 range[0] = 127; 117 range[1] = 127; 118 *precision = 23; 119 break; 120 default: 121 NOTREACHED(); 122 break; 123 } 124 125 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 && 126 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) { 127 // This function is sometimes defined even though it's really just 128 // a stub, so we need to set range and precision as if it weren't 129 // defined before calling it. 130 // On Mac OS with some GPUs, calling this generates a 131 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2 132 // platforms. 133 glGetShaderPrecisionFormat(shader_type, precision_type, 134 range, precision); 135 136 // TODO(brianderson): Make the following official workarounds. 137 138 // Some drivers have bugs where they report the ranges as a negative number. 139 // Taking the absolute value here shouldn't hurt because negative numbers 140 // aren't expected anyway. 141 range[0] = abs(range[0]); 142 range[1] = abs(range[1]); 143 144 // If the driver reports a precision for highp float that isn't actually 145 // highp, don't pretend like it's supported because shader compilation will 146 // fail anyway. 147 if (precision_type == GL_HIGH_FLOAT && 148 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) { 149 range[0] = 0; 150 range[1] = 0; 151 *precision = 0; 152 } 153 } 154 } 155 156 } // namespace 157 158 class GLES2DecoderImpl; 159 160 // Local versions of the SET_GL_ERROR macros 161 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \ 162 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg) 163 #define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \ 164 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \ 165 function_name, value, label) 166 #define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \ 167 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \ 168 function_name, pname) 169 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \ 170 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \ 171 function_name) 172 #define LOCAL_PEEK_GL_ERROR(function_name) \ 173 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name) 174 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \ 175 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name) 176 #define LOCAL_PERFORMANCE_WARNING(msg) \ 177 PerformanceWarning(__FILE__, __LINE__, msg) 178 #define LOCAL_RENDER_WARNING(msg) \ 179 RenderWarning(__FILE__, __LINE__, msg) 180 181 // Check that certain assumptions the code makes are true. There are places in 182 // the code where shared memory is passed direclty to GL. Example, glUniformiv, 183 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe 184 // a few others) are 32bits. If they are not 32bits the code will have to change 185 // to call those GL functions with service side memory and then copy the results 186 // to shared memory, converting the sizes. 187 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT 188 GLint_not_same_size_as_uint32); 189 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT 190 GLint_not_same_size_as_uint32); 191 COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT 192 GLfloat_not_same_size_as_float); 193 194 // TODO(kbr): the use of this anonymous namespace core dumps the 195 // linker on Mac OS X 10.6 when the symbol ordering file is used 196 // namespace { 197 198 // Returns the address of the first byte after a struct. 199 template <typename T> 200 const void* AddressAfterStruct(const T& pod) { 201 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); 202 } 203 204 // Returns the address of the frst byte after the struct or NULL if size > 205 // immediate_data_size. 206 template <typename RETURN_TYPE, typename COMMAND_TYPE> 207 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod, 208 uint32 size, 209 uint32 immediate_data_size) { 210 return (size <= immediate_data_size) ? 211 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) : 212 NULL; 213 } 214 215 // Computes the data size for certain gl commands like glUniform. 216 bool ComputeDataSize( 217 GLuint count, 218 size_t size, 219 unsigned int elements_per_unit, 220 uint32* dst) { 221 uint32 value; 222 if (!SafeMultiplyUint32(count, size, &value)) { 223 return false; 224 } 225 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) { 226 return false; 227 } 228 *dst = value; 229 return true; 230 } 231 232 // A struct to hold info about each command. 233 struct CommandInfo { 234 uint8 arg_flags; // How to handle the arguments for this command 235 uint8 cmd_flags; // How to handle this command 236 uint16 arg_count; // How many arguments are expected for this command. 237 }; 238 239 // cmds::name::cmd_flags, 240 // A table of CommandInfo for all the commands. 241 const CommandInfo g_command_info[] = { 242 #define GLES2_CMD_OP(name) { \ 243 cmds::name::kArgFlags, \ 244 cmds::name::cmd_flags, \ 245 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ 246 247 GLES2_COMMAND_LIST(GLES2_CMD_OP) 248 249 #undef GLES2_CMD_OP 250 }; 251 252 // Return true if a character belongs to the ASCII subset as defined in 253 // GLSL ES 1.0 spec section 3.1. 254 static bool CharacterIsValidForGLES(unsigned char c) { 255 // Printing characters are valid except " $ ` @ \ ' DEL. 256 if (c >= 32 && c <= 126 && 257 c != '"' && 258 c != '$' && 259 c != '`' && 260 c != '@' && 261 c != '\\' && 262 c != '\'') { 263 return true; 264 } 265 // Horizontal tab, line feed, vertical tab, form feed, carriage return 266 // are also valid. 267 if (c >= 9 && c <= 13) { 268 return true; 269 } 270 271 return false; 272 } 273 274 static bool StringIsValidForGLES(const char* str) { 275 for (; *str; ++str) { 276 if (!CharacterIsValidForGLES(*str)) { 277 return false; 278 } 279 } 280 return true; 281 } 282 283 // This class prevents any GL errors that occur when it is in scope from 284 // being reported to the client. 285 class ScopedGLErrorSuppressor { 286 public: 287 explicit ScopedGLErrorSuppressor( 288 const char* function_name, ErrorState* error_state); 289 ~ScopedGLErrorSuppressor(); 290 private: 291 const char* function_name_; 292 ErrorState* error_state_; 293 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); 294 }; 295 296 // Temporarily changes a decoder's bound texture and restore it when this 297 // object goes out of scope. Also temporarily switches to using active texture 298 // unit zero in case the client has changed that to something invalid. 299 class ScopedTextureBinder { 300 public: 301 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target); 302 ~ScopedTextureBinder(); 303 304 private: 305 ContextState* state_; 306 GLenum target_; 307 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder); 308 }; 309 310 // Temporarily changes a decoder's bound render buffer and restore it when this 311 // object goes out of scope. 312 class ScopedRenderBufferBinder { 313 public: 314 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id); 315 ~ScopedRenderBufferBinder(); 316 317 private: 318 ContextState* state_; 319 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); 320 }; 321 322 // Temporarily changes a decoder's bound frame buffer and restore it when this 323 // object goes out of scope. 324 class ScopedFrameBufferBinder { 325 public: 326 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); 327 ~ScopedFrameBufferBinder(); 328 329 private: 330 GLES2DecoderImpl* decoder_; 331 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); 332 }; 333 334 // Temporarily changes a decoder's bound frame buffer to a resolved version of 335 // the multisampled offscreen render buffer if that buffer is multisampled, and, 336 // if it is bound or enforce_internal_framebuffer is true. If internal is 337 // true, the resolved framebuffer is not visible to the parent. 338 class ScopedResolvedFrameBufferBinder { 339 public: 340 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder, 341 bool enforce_internal_framebuffer, 342 bool internal); 343 ~ScopedResolvedFrameBufferBinder(); 344 345 private: 346 GLES2DecoderImpl* decoder_; 347 bool resolve_and_bind_; 348 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); 349 }; 350 351 class ScopedModifyPixels { 352 public: 353 explicit ScopedModifyPixels(TextureRef* ref); 354 ~ScopedModifyPixels(); 355 356 private: 357 TextureRef* ref_; 358 }; 359 360 ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) { 361 if (ref_) 362 ref_->texture()->OnWillModifyPixels(); 363 } 364 365 ScopedModifyPixels::~ScopedModifyPixels() { 366 if (ref_) 367 ref_->texture()->OnDidModifyPixels(); 368 } 369 370 class ScopedRenderTo { 371 public: 372 explicit ScopedRenderTo(Framebuffer* framebuffer); 373 ~ScopedRenderTo(); 374 375 private: 376 const Framebuffer* framebuffer_; 377 }; 378 379 ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer) 380 : framebuffer_(framebuffer) { 381 if (framebuffer) 382 framebuffer_->OnWillRenderTo(); 383 } 384 385 ScopedRenderTo::~ScopedRenderTo() { 386 if (framebuffer_) 387 framebuffer_->OnDidRenderTo(); 388 } 389 390 // Encapsulates an OpenGL texture. 391 class BackTexture { 392 public: 393 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state); 394 ~BackTexture(); 395 396 // Create a new render texture. 397 void Create(); 398 399 // Set the initial size and format of a render texture or resize it. 400 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero); 401 402 // Copy the contents of the currently bound frame buffer. 403 void Copy(const gfx::Size& size, GLenum format); 404 405 // Destroy the render texture. This must be explicitly called before 406 // destroying this object. 407 void Destroy(); 408 409 // Invalidate the texture. This can be used when a context is lost and it is 410 // not possible to make it current in order to free the resource. 411 void Invalidate(); 412 413 GLuint id() const { 414 return id_; 415 } 416 417 gfx::Size size() const { 418 return size_; 419 } 420 421 private: 422 MemoryTypeTracker memory_tracker_; 423 ContextState* state_; 424 size_t bytes_allocated_; 425 GLuint id_; 426 gfx::Size size_; 427 DISALLOW_COPY_AND_ASSIGN(BackTexture); 428 }; 429 430 // Encapsulates an OpenGL render buffer of any format. 431 class BackRenderbuffer { 432 public: 433 explicit BackRenderbuffer( 434 RenderbufferManager* renderbuffer_manager, 435 MemoryTracker* memory_tracker, 436 ContextState* state); 437 ~BackRenderbuffer(); 438 439 // Create a new render buffer. 440 void Create(); 441 442 // Set the initial size and format of a render buffer or resize it. 443 bool AllocateStorage(const FeatureInfo* feature_info, 444 const gfx::Size& size, 445 GLenum format, 446 GLsizei samples); 447 448 // Destroy the render buffer. This must be explicitly called before destroying 449 // this object. 450 void Destroy(); 451 452 // Invalidate the render buffer. This can be used when a context is lost and 453 // it is not possible to make it current in order to free the resource. 454 void Invalidate(); 455 456 GLuint id() const { 457 return id_; 458 } 459 460 private: 461 RenderbufferManager* renderbuffer_manager_; 462 MemoryTypeTracker memory_tracker_; 463 ContextState* state_; 464 size_t bytes_allocated_; 465 GLuint id_; 466 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer); 467 }; 468 469 // Encapsulates an OpenGL frame buffer. 470 class BackFramebuffer { 471 public: 472 explicit BackFramebuffer(GLES2DecoderImpl* decoder); 473 ~BackFramebuffer(); 474 475 // Create a new frame buffer. 476 void Create(); 477 478 // Attach a color render buffer to a frame buffer. 479 void AttachRenderTexture(BackTexture* texture); 480 481 // Attach a render buffer to a frame buffer. Note that this unbinds any 482 // currently bound frame buffer. 483 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer); 484 485 // Destroy the frame buffer. This must be explicitly called before destroying 486 // this object. 487 void Destroy(); 488 489 // Invalidate the frame buffer. This can be used when a context is lost and it 490 // is not possible to make it current in order to free the resource. 491 void Invalidate(); 492 493 // See glCheckFramebufferStatusEXT. 494 GLenum CheckStatus(); 495 496 GLuint id() const { 497 return id_; 498 } 499 500 private: 501 GLES2DecoderImpl* decoder_; 502 GLuint id_; 503 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer); 504 }; 505 506 struct FenceCallback { 507 explicit FenceCallback() 508 : fence(gfx::GLFence::Create()) { 509 DCHECK(fence); 510 } 511 std::vector<base::Closure> callbacks; 512 scoped_ptr<gfx::GLFence> fence; 513 }; 514 515 class AsyncUploadTokenCompletionObserver 516 : public AsyncPixelTransferCompletionObserver { 517 public: 518 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token) 519 : async_upload_token_(async_upload_token) { 520 } 521 522 virtual void DidComplete(const AsyncMemoryParams& mem_params) OVERRIDE { 523 DCHECK(mem_params.buffer()); 524 void* data = mem_params.GetDataAddress(); 525 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data); 526 sync->SetAsyncUploadToken(async_upload_token_); 527 } 528 529 private: 530 virtual ~AsyncUploadTokenCompletionObserver() { 531 } 532 533 uint32 async_upload_token_; 534 535 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver); 536 }; 537 538 // } // anonymous namespace. 539 540 bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, 541 uint32* service_texture_id) { 542 return false; 543 } 544 545 GLES2Decoder::GLES2Decoder() 546 : initialized_(false), 547 debug_(false), 548 log_commands_(false) { 549 } 550 551 GLES2Decoder::~GLES2Decoder() { 552 } 553 554 void GLES2Decoder::BeginDecoding() {} 555 556 void GLES2Decoder::EndDecoding() {} 557 558 // This class implements GLES2Decoder so we don't have to expose all the GLES2 559 // cmd stuff to outside this class. 560 class GLES2DecoderImpl : public GLES2Decoder, 561 public FramebufferManager::TextureDetachObserver, 562 public ErrorStateClient { 563 public: 564 explicit GLES2DecoderImpl(ContextGroup* group); 565 virtual ~GLES2DecoderImpl(); 566 567 // Overridden from AsyncAPIInterface. 568 virtual Error DoCommand(unsigned int command, 569 unsigned int arg_count, 570 const void* args) OVERRIDE; 571 572 // Overridden from AsyncAPIInterface. 573 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE; 574 575 // Overridden from GLES2Decoder. 576 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, 577 const scoped_refptr<gfx::GLContext>& context, 578 bool offscreen, 579 const gfx::Size& size, 580 const DisallowedFeatures& disallowed_features, 581 const std::vector<int32>& attribs) OVERRIDE; 582 virtual void Destroy(bool have_context) OVERRIDE; 583 virtual void SetSurface( 584 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE; 585 virtual void ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE; 586 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE; 587 void UpdateParentTextureInfo(); 588 virtual bool MakeCurrent() OVERRIDE; 589 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; } 590 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); } 591 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); } 592 virtual Capabilities GetCapabilities() OVERRIDE; 593 virtual void RestoreState(const ContextState* prev_state) const OVERRIDE; 594 595 virtual void RestoreActiveTexture() const OVERRIDE { 596 state_.RestoreActiveTexture(); 597 } 598 virtual void RestoreAllTextureUnitBindings( 599 const ContextState* prev_state) const OVERRIDE { 600 state_.RestoreAllTextureUnitBindings(prev_state); 601 } 602 virtual void RestoreActiveTextureUnitBinding( 603 unsigned int target) const OVERRIDE { 604 state_.RestoreActiveTextureUnitBinding(target); 605 } 606 virtual void RestoreBufferBindings() const OVERRIDE { 607 state_.RestoreBufferBindings(); 608 } 609 virtual void RestoreGlobalState() const OVERRIDE { 610 state_.RestoreGlobalState(NULL); 611 } 612 virtual void RestoreProgramBindings() const OVERRIDE { 613 state_.RestoreProgramBindings(); 614 } 615 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE { 616 state_.RestoreTextureUnitBindings(unit, NULL); 617 } 618 virtual void RestoreFramebufferBindings() const OVERRIDE; 619 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE; 620 621 virtual void ClearAllAttributes() const OVERRIDE; 622 virtual void RestoreAllAttributes() const OVERRIDE; 623 624 virtual QueryManager* GetQueryManager() OVERRIDE { 625 return query_manager_.get(); 626 } 627 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE { 628 return vertex_array_manager_.get(); 629 } 630 virtual bool ProcessPendingQueries() OVERRIDE; 631 virtual bool HasMoreIdleWork() OVERRIDE; 632 virtual void PerformIdleWork() OVERRIDE; 633 634 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE; 635 636 virtual void SetResizeCallback( 637 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE; 638 639 virtual Logger* GetLogger() OVERRIDE; 640 641 virtual void BeginDecoding() OVERRIDE; 642 virtual void EndDecoding() OVERRIDE; 643 644 virtual ErrorState* GetErrorState() OVERRIDE; 645 virtual const ContextState* GetContextState() OVERRIDE { return &state_; } 646 647 virtual void SetShaderCacheCallback( 648 const ShaderCacheCallback& callback) OVERRIDE; 649 virtual void SetWaitSyncPointCallback( 650 const WaitSyncPointCallback& callback) OVERRIDE; 651 652 virtual AsyncPixelTransferManager* 653 GetAsyncPixelTransferManager() OVERRIDE; 654 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE; 655 virtual void SetAsyncPixelTransferManagerForTest( 656 AsyncPixelTransferManager* manager) OVERRIDE; 657 virtual void SetIgnoreCachedStateForTest(bool ignore) OVERRIDE; 658 void ProcessFinishedAsyncTransfers(); 659 660 virtual bool GetServiceTextureId(uint32 client_texture_id, 661 uint32* service_texture_id) OVERRIDE; 662 663 virtual uint32 GetTextureUploadCount() OVERRIDE; 664 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; 665 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; 666 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE; 667 668 // Restores the current state to the user's settings. 669 void RestoreCurrentFramebufferBindings(); 670 671 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. 672 void ApplyDirtyState(); 673 674 // These check the state of the currently bound framebuffer or the 675 // backbuffer if no framebuffer is bound. 676 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise 677 // check with all attached and enabled color attachments. 678 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers); 679 bool BoundFramebufferHasDepthAttachment(); 680 bool BoundFramebufferHasStencilAttachment(); 681 682 virtual error::ContextLostReason GetContextLostReason() OVERRIDE; 683 684 // Overridden from FramebufferManager::TextureDetachObserver: 685 virtual void OnTextureRefDetachedFromFramebuffer( 686 TextureRef* texture) OVERRIDE; 687 688 // Overriden from ErrorStateClient. 689 virtual void OnOutOfMemoryError() OVERRIDE; 690 691 // Helpers to facilitate calling into compatible extensions. 692 static void RenderbufferStorageMultisampleHelper( 693 const FeatureInfo* feature_info, 694 GLenum target, 695 GLsizei samples, 696 GLenum internal_format, 697 GLsizei width, 698 GLsizei height); 699 700 void BlitFramebufferHelper(GLint srcX0, 701 GLint srcY0, 702 GLint srcX1, 703 GLint srcY1, 704 GLint dstX0, 705 GLint dstY0, 706 GLint dstX1, 707 GLint dstY1, 708 GLbitfield mask, 709 GLenum filter); 710 711 private: 712 friend class ScopedFrameBufferBinder; 713 friend class ScopedResolvedFrameBufferBinder; 714 friend class BackFramebuffer; 715 716 // Initialize or re-initialize the shader translator. 717 bool InitializeShaderTranslator(); 718 719 void UpdateCapabilities(); 720 721 // Helpers for the glGen and glDelete functions. 722 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids); 723 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids); 724 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids); 725 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); 726 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); 727 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); 728 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 729 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 730 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 731 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 732 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 733 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 734 735 // Helper for async upload token completion notification callback. 736 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token, 737 uint32 sync_data_shm_id, 738 uint32 sync_data_shm_offset); 739 740 741 742 // Workarounds 743 void OnFboChanged() const; 744 void OnUseFramebuffer() const; 745 746 // TODO(gman): Cache these pointers? 747 BufferManager* buffer_manager() { 748 return group_->buffer_manager(); 749 } 750 751 RenderbufferManager* renderbuffer_manager() { 752 return group_->renderbuffer_manager(); 753 } 754 755 FramebufferManager* framebuffer_manager() { 756 return group_->framebuffer_manager(); 757 } 758 759 ProgramManager* program_manager() { 760 return group_->program_manager(); 761 } 762 763 ShaderManager* shader_manager() { 764 return group_->shader_manager(); 765 } 766 767 ShaderTranslatorCache* shader_translator_cache() { 768 return group_->shader_translator_cache(); 769 } 770 771 const TextureManager* texture_manager() const { 772 return group_->texture_manager(); 773 } 774 775 TextureManager* texture_manager() { 776 return group_->texture_manager(); 777 } 778 779 MailboxManager* mailbox_manager() { 780 return group_->mailbox_manager(); 781 } 782 783 ImageManager* image_manager() { 784 return group_->image_manager(); 785 } 786 787 VertexArrayManager* vertex_array_manager() { 788 return vertex_array_manager_.get(); 789 } 790 791 MemoryTracker* memory_tracker() { 792 return group_->memory_tracker(); 793 } 794 795 bool EnsureGPUMemoryAvailable(size_t estimated_size) { 796 MemoryTracker* tracker = memory_tracker(); 797 if (tracker) { 798 return tracker->EnsureGPUMemoryAvailable(estimated_size); 799 } 800 return true; 801 } 802 803 bool IsOffscreenBufferMultisampled() const { 804 return offscreen_target_samples_ > 1; 805 } 806 807 // Creates a Texture for the given texture. 808 TextureRef* CreateTexture( 809 GLuint client_id, GLuint service_id) { 810 return texture_manager()->CreateTexture(client_id, service_id); 811 } 812 813 // Gets the texture info for the given texture. Returns NULL if none exists. 814 TextureRef* GetTexture(GLuint client_id) const { 815 return texture_manager()->GetTexture(client_id); 816 } 817 818 // Deletes the texture info for the given texture. 819 void RemoveTexture(GLuint client_id) { 820 texture_manager()->RemoveTexture(client_id); 821 } 822 823 // Get the size (in pixels) of the currently bound frame buffer (either FBO 824 // or regular back buffer). 825 gfx::Size GetBoundReadFrameBufferSize(); 826 827 // Get the format of the currently bound frame buffer (either FBO or regular 828 // back buffer) 829 GLenum GetBoundReadFrameBufferTextureType(); 830 GLenum GetBoundReadFrameBufferInternalFormat(); 831 GLenum GetBoundDrawFrameBufferInternalFormat(); 832 833 // Wrapper for CompressedTexImage2D commands. 834 error::Error DoCompressedTexImage2D( 835 GLenum target, 836 GLint level, 837 GLenum internal_format, 838 GLsizei width, 839 GLsizei height, 840 GLint border, 841 GLsizei image_size, 842 const void* data); 843 844 // Wrapper for CompressedTexSubImage2D. 845 void DoCompressedTexSubImage2D( 846 GLenum target, 847 GLint level, 848 GLint xoffset, 849 GLint yoffset, 850 GLsizei width, 851 GLsizei height, 852 GLenum format, 853 GLsizei imageSize, 854 const void * data); 855 856 // Wrapper for CopyTexImage2D. 857 void DoCopyTexImage2D( 858 GLenum target, 859 GLint level, 860 GLenum internal_format, 861 GLint x, 862 GLint y, 863 GLsizei width, 864 GLsizei height, 865 GLint border); 866 867 // Wrapper for SwapBuffers. 868 void DoSwapBuffers(); 869 870 // Wrapper for CopyTexSubImage2D. 871 void DoCopyTexSubImage2D( 872 GLenum target, 873 GLint level, 874 GLint xoffset, 875 GLint yoffset, 876 GLint x, 877 GLint y, 878 GLsizei width, 879 GLsizei height); 880 881 // Validation for TexSubImage2D. 882 bool ValidateTexSubImage2D( 883 error::Error* error, 884 const char* function_name, 885 GLenum target, 886 GLint level, 887 GLint xoffset, 888 GLint yoffset, 889 GLsizei width, 890 GLsizei height, 891 GLenum format, 892 GLenum type, 893 const void * data); 894 895 // Wrapper for TexSubImage2D. 896 error::Error DoTexSubImage2D( 897 GLenum target, 898 GLint level, 899 GLint xoffset, 900 GLint yoffset, 901 GLsizei width, 902 GLsizei height, 903 GLenum format, 904 GLenum type, 905 const void * data); 906 907 // Extra validation for async tex(Sub)Image2D. 908 bool ValidateAsyncTransfer( 909 const char* function_name, 910 TextureRef* texture_ref, 911 GLenum target, 912 GLint level, 913 const void * data); 914 915 // Wrapper for TexImageIOSurface2DCHROMIUM. 916 void DoTexImageIOSurface2DCHROMIUM( 917 GLenum target, 918 GLsizei width, 919 GLsizei height, 920 GLuint io_surface_id, 921 GLuint plane); 922 923 void DoCopyTextureCHROMIUM( 924 GLenum target, 925 GLuint source_id, 926 GLuint target_id, 927 GLint level, 928 GLenum internal_format, 929 GLenum dest_type); 930 931 // Wrapper for TexStorage2DEXT. 932 void DoTexStorage2DEXT( 933 GLenum target, 934 GLint levels, 935 GLenum internal_format, 936 GLsizei width, 937 GLsizei height); 938 939 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); 940 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, 941 const GLbyte* key); 942 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref, 943 GLenum target, const GLbyte* data); 944 945 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); 946 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key, 947 GLuint client_id); 948 949 void DoBindTexImage2DCHROMIUM( 950 GLenum target, 951 GLint image_id); 952 void DoReleaseTexImage2DCHROMIUM( 953 GLenum target, 954 GLint image_id); 955 956 void DoTraceEndCHROMIUM(void); 957 958 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs); 959 960 void DoLoseContextCHROMIUM(GLenum current, GLenum other); 961 962 // Creates a Program for the given program. 963 Program* CreateProgram( 964 GLuint client_id, GLuint service_id) { 965 return program_manager()->CreateProgram(client_id, service_id); 966 } 967 968 // Gets the program info for the given program. Returns NULL if none exists. 969 Program* GetProgram(GLuint client_id) { 970 return program_manager()->GetProgram(client_id); 971 } 972 973 #if defined(NDEBUG) 974 void LogClientServiceMapping( 975 const char* /* function_name */, 976 GLuint /* client_id */, 977 GLuint /* service_id */) { 978 } 979 template<typename T> 980 void LogClientServiceForInfo( 981 T* /* info */, GLuint /* client_id */, const char* /* function_name */) { 982 } 983 #else 984 void LogClientServiceMapping( 985 const char* function_name, GLuint client_id, GLuint service_id) { 986 if (service_logging_) { 987 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name 988 << ": client_id = " << client_id 989 << ", service_id = " << service_id; 990 } 991 } 992 template<typename T> 993 void LogClientServiceForInfo( 994 T* info, GLuint client_id, const char* function_name) { 995 if (info) { 996 LogClientServiceMapping(function_name, client_id, info->service_id()); 997 } 998 } 999 #endif 1000 1001 // Gets the program info for the given program. If it's not a program 1002 // generates a GL error. Returns NULL if not program. 1003 Program* GetProgramInfoNotShader( 1004 GLuint client_id, const char* function_name) { 1005 Program* program = GetProgram(client_id); 1006 if (!program) { 1007 if (GetShader(client_id)) { 1008 LOCAL_SET_GL_ERROR( 1009 GL_INVALID_OPERATION, function_name, "shader passed for program"); 1010 } else { 1011 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program"); 1012 } 1013 } 1014 LogClientServiceForInfo(program, client_id, function_name); 1015 return program; 1016 } 1017 1018 1019 // Creates a Shader for the given shader. 1020 Shader* CreateShader( 1021 GLuint client_id, 1022 GLuint service_id, 1023 GLenum shader_type) { 1024 return shader_manager()->CreateShader( 1025 client_id, service_id, shader_type); 1026 } 1027 1028 // Gets the shader info for the given shader. Returns NULL if none exists. 1029 Shader* GetShader(GLuint client_id) { 1030 return shader_manager()->GetShader(client_id); 1031 } 1032 1033 // Gets the shader info for the given shader. If it's not a shader generates a 1034 // GL error. Returns NULL if not shader. 1035 Shader* GetShaderInfoNotProgram( 1036 GLuint client_id, const char* function_name) { 1037 Shader* shader = GetShader(client_id); 1038 if (!shader) { 1039 if (GetProgram(client_id)) { 1040 LOCAL_SET_GL_ERROR( 1041 GL_INVALID_OPERATION, function_name, "program passed for shader"); 1042 } else { 1043 LOCAL_SET_GL_ERROR( 1044 GL_INVALID_VALUE, function_name, "unknown shader"); 1045 } 1046 } 1047 LogClientServiceForInfo(shader, client_id, function_name); 1048 return shader; 1049 } 1050 1051 // Creates a buffer info for the given buffer. 1052 void CreateBuffer(GLuint client_id, GLuint service_id) { 1053 return buffer_manager()->CreateBuffer(client_id, service_id); 1054 } 1055 1056 // Gets the buffer info for the given buffer. 1057 Buffer* GetBuffer(GLuint client_id) { 1058 Buffer* buffer = buffer_manager()->GetBuffer(client_id); 1059 return buffer; 1060 } 1061 1062 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used 1063 // on glDeleteBuffers so we can make sure the user does not try to render 1064 // with deleted buffers. 1065 void RemoveBuffer(GLuint client_id); 1066 1067 // Creates a framebuffer info for the given framebuffer. 1068 void CreateFramebuffer(GLuint client_id, GLuint service_id) { 1069 return framebuffer_manager()->CreateFramebuffer(client_id, service_id); 1070 } 1071 1072 // Gets the framebuffer info for the given framebuffer. 1073 Framebuffer* GetFramebuffer(GLuint client_id) { 1074 return framebuffer_manager()->GetFramebuffer(client_id); 1075 } 1076 1077 // Removes the framebuffer info for the given framebuffer. 1078 void RemoveFramebuffer(GLuint client_id) { 1079 framebuffer_manager()->RemoveFramebuffer(client_id); 1080 } 1081 1082 // Creates a renderbuffer info for the given renderbuffer. 1083 void CreateRenderbuffer(GLuint client_id, GLuint service_id) { 1084 return renderbuffer_manager()->CreateRenderbuffer( 1085 client_id, service_id); 1086 } 1087 1088 // Gets the renderbuffer info for the given renderbuffer. 1089 Renderbuffer* GetRenderbuffer(GLuint client_id) { 1090 return renderbuffer_manager()->GetRenderbuffer(client_id); 1091 } 1092 1093 // Removes the renderbuffer info for the given renderbuffer. 1094 void RemoveRenderbuffer(GLuint client_id) { 1095 renderbuffer_manager()->RemoveRenderbuffer(client_id); 1096 } 1097 1098 // Gets the vertex attrib manager for the given vertex array. 1099 VertexAttribManager* GetVertexAttribManager(GLuint client_id) { 1100 VertexAttribManager* info = 1101 vertex_array_manager()->GetVertexAttribManager(client_id); 1102 return info; 1103 } 1104 1105 // Removes the vertex attrib manager for the given vertex array. 1106 void RemoveVertexAttribManager(GLuint client_id) { 1107 vertex_array_manager()->RemoveVertexAttribManager(client_id); 1108 } 1109 1110 // Creates a vertex attrib manager for the given vertex array. 1111 scoped_refptr<VertexAttribManager> CreateVertexAttribManager( 1112 GLuint client_id, 1113 GLuint service_id, 1114 bool client_visible) { 1115 return vertex_array_manager()->CreateVertexAttribManager( 1116 client_id, service_id, group_->max_vertex_attribs(), client_visible); 1117 } 1118 1119 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name); 1120 void DoBindUniformLocationCHROMIUM( 1121 GLuint client_id, GLint location, const char* name); 1122 1123 error::Error GetAttribLocationHelper( 1124 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 1125 const std::string& name_str); 1126 1127 error::Error GetUniformLocationHelper( 1128 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 1129 const std::string& name_str); 1130 1131 // Helper for glShaderSource. 1132 error::Error ShaderSourceHelper( 1133 GLuint client_id, const char* data, uint32 data_size); 1134 1135 // Clear any textures used by the current program. 1136 bool ClearUnclearedTextures(); 1137 1138 // Clears any uncleared attachments attached to the given frame buffer. 1139 // Returns false if there was a generated GL error. 1140 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer); 1141 1142 // overridden from GLES2Decoder 1143 virtual bool ClearLevel(unsigned service_id, 1144 unsigned bind_target, 1145 unsigned target, 1146 int level, 1147 unsigned internal_format, 1148 unsigned format, 1149 unsigned type, 1150 int width, 1151 int height, 1152 bool is_texture_immutable) OVERRIDE; 1153 1154 // Restore all GL state that affects clearing. 1155 void RestoreClearState(); 1156 1157 // Remembers the state of some capabilities. 1158 // Returns: true if glEnable/glDisable should actually be called. 1159 bool SetCapabilityState(GLenum cap, bool enabled); 1160 1161 // Check that the currently bound framebuffers are valid. 1162 // Generates GL error if not. 1163 bool CheckBoundFramebuffersValid(const char* func_name); 1164 1165 // Check if a framebuffer meets our requirements. 1166 bool CheckFramebufferValid( 1167 Framebuffer* framebuffer, 1168 GLenum target, 1169 const char* func_name); 1170 1171 // Checks if the current program exists and is valid. If not generates the 1172 // appropriate GL error. Returns true if the current program is in a usable 1173 // state. 1174 bool CheckCurrentProgram(const char* function_name); 1175 1176 // Checks if the current program exists and is valid and that location is not 1177 // -1. If the current program is not valid generates the appropriate GL 1178 // error. Returns true if the current program is in a usable state and 1179 // location is not -1. 1180 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); 1181 1182 // Gets the type of a uniform for a location in the current program. Sets GL 1183 // errors if the current program is not valid. Returns true if the current 1184 // program is valid and the location exists. Adjusts count so it 1185 // does not overflow the uniform. 1186 bool PrepForSetUniformByLocation(GLint fake_location, 1187 const char* function_name, 1188 Program::UniformApiType api_type, 1189 GLint* real_location, 1190 GLenum* type, 1191 GLsizei* count); 1192 1193 // Gets the service id for any simulated backbuffer fbo. 1194 GLuint GetBackbufferServiceId() const; 1195 1196 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv 1197 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written); 1198 1199 // Helper for glGetVertexAttrib 1200 void GetVertexAttribHelper( 1201 const VertexAttrib* attrib, GLenum pname, GLint* param); 1202 1203 // Wrapper for glCreateProgram 1204 bool CreateProgramHelper(GLuint client_id); 1205 1206 // Wrapper for glCreateShader 1207 bool CreateShaderHelper(GLenum type, GLuint client_id); 1208 1209 // Wrapper for glActiveTexture 1210 void DoActiveTexture(GLenum texture_unit); 1211 1212 // Wrapper for glAttachShader 1213 void DoAttachShader(GLuint client_program_id, GLint client_shader_id); 1214 1215 // Wrapper for glBindBuffer since we need to track the current targets. 1216 void DoBindBuffer(GLenum target, GLuint buffer); 1217 1218 // Wrapper for glBindFramebuffer since we need to track the current targets. 1219 void DoBindFramebuffer(GLenum target, GLuint framebuffer); 1220 1221 // Wrapper for glBindRenderbuffer since we need to track the current targets. 1222 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer); 1223 1224 // Wrapper for glBindTexture since we need to track the current targets. 1225 void DoBindTexture(GLenum target, GLuint texture); 1226 1227 // Wrapper for glBindVertexArrayOES 1228 void DoBindVertexArrayOES(GLuint array); 1229 void EmulateVertexArrayState(); 1230 1231 // Wrapper for glBlitFramebufferCHROMIUM. 1232 void DoBlitFramebufferCHROMIUM( 1233 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1234 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1235 GLbitfield mask, GLenum filter); 1236 1237 // Wrapper for glBufferSubData. 1238 void DoBufferSubData( 1239 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); 1240 1241 // Wrapper for glCheckFramebufferStatus 1242 GLenum DoCheckFramebufferStatus(GLenum target); 1243 1244 // Wrapper for glClear 1245 error::Error DoClear(GLbitfield mask); 1246 1247 // Wrappers for various state. 1248 void DoDepthRangef(GLclampf znear, GLclampf zfar); 1249 void DoSampleCoverage(GLclampf value, GLboolean invert); 1250 1251 // Wrapper for glCompileShader. 1252 void DoCompileShader(GLuint shader); 1253 1254 // Helper for DeleteSharedIdsCHROMIUM commands. 1255 void DoDeleteSharedIdsCHROMIUM( 1256 GLuint namespace_id, GLsizei n, const GLuint* ids); 1257 1258 // Wrapper for glDetachShader 1259 void DoDetachShader(GLuint client_program_id, GLint client_shader_id); 1260 1261 // Wrapper for glDisable 1262 void DoDisable(GLenum cap); 1263 1264 // Wrapper for glDisableVertexAttribArray. 1265 void DoDisableVertexAttribArray(GLuint index); 1266 1267 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined 1268 // attachments. 1269 void DoDiscardFramebufferEXT(GLenum target, 1270 GLsizei numAttachments, 1271 const GLenum* attachments); 1272 1273 // Wrapper for glEnable 1274 void DoEnable(GLenum cap); 1275 1276 // Wrapper for glEnableVertexAttribArray. 1277 void DoEnableVertexAttribArray(GLuint index); 1278 1279 // Wrapper for glFinish. 1280 void DoFinish(); 1281 1282 // Wrapper for glFlush. 1283 void DoFlush(); 1284 1285 // Wrapper for glFramebufferRenderbufffer. 1286 void DoFramebufferRenderbuffer( 1287 GLenum target, GLenum attachment, GLenum renderbuffertarget, 1288 GLuint renderbuffer); 1289 1290 // Wrapper for glFramebufferTexture2D. 1291 void DoFramebufferTexture2D( 1292 GLenum target, GLenum attachment, GLenum textarget, GLuint texture, 1293 GLint level); 1294 1295 // Wrapper for glFramebufferTexture2DMultisampleEXT. 1296 void DoFramebufferTexture2DMultisample( 1297 GLenum target, GLenum attachment, GLenum textarget, 1298 GLuint texture, GLint level, GLsizei samples); 1299 1300 // Common implementation for both DoFramebufferTexture2D wrappers. 1301 void DoFramebufferTexture2DCommon(const char* name, 1302 GLenum target, GLenum attachment, GLenum textarget, 1303 GLuint texture, GLint level, GLsizei samples); 1304 1305 // Wrapper for glGenerateMipmap 1306 void DoGenerateMipmap(GLenum target); 1307 1308 // Helper for GenSharedIdsCHROMIUM commands. 1309 void DoGenSharedIdsCHROMIUM( 1310 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); 1311 1312 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname 1313 // to account for different pname values defined in different extension 1314 // variants. 1315 GLenum AdjustGetPname(GLenum pname); 1316 1317 // Wrapper for DoGetBooleanv. 1318 void DoGetBooleanv(GLenum pname, GLboolean* params); 1319 1320 // Wrapper for DoGetFloatv. 1321 void DoGetFloatv(GLenum pname, GLfloat* params); 1322 1323 // Wrapper for glGetFramebufferAttachmentParameteriv. 1324 void DoGetFramebufferAttachmentParameteriv( 1325 GLenum target, GLenum attachment, GLenum pname, GLint* params); 1326 1327 // Wrapper for glGetIntegerv. 1328 void DoGetIntegerv(GLenum pname, GLint* params); 1329 1330 // Gets the max value in a range in a buffer. 1331 GLuint DoGetMaxValueInBufferCHROMIUM( 1332 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); 1333 1334 // Wrapper for glGetBufferParameteriv. 1335 void DoGetBufferParameteriv( 1336 GLenum target, GLenum pname, GLint* params); 1337 1338 // Wrapper for glGetProgramiv. 1339 void DoGetProgramiv( 1340 GLuint program_id, GLenum pname, GLint* params); 1341 1342 // Wrapper for glRenderbufferParameteriv. 1343 void DoGetRenderbufferParameteriv( 1344 GLenum target, GLenum pname, GLint* params); 1345 1346 // Wrapper for glGetShaderiv 1347 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params); 1348 1349 // Wrappers for glGetTexParameter. 1350 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); 1351 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params); 1352 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname); 1353 1354 // Wrappers for glGetVertexAttrib. 1355 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); 1356 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params); 1357 1358 // Wrappers for glIsXXX functions. 1359 bool DoIsEnabled(GLenum cap); 1360 bool DoIsBuffer(GLuint client_id); 1361 bool DoIsFramebuffer(GLuint client_id); 1362 bool DoIsProgram(GLuint client_id); 1363 bool DoIsRenderbuffer(GLuint client_id); 1364 bool DoIsShader(GLuint client_id); 1365 bool DoIsTexture(GLuint client_id); 1366 bool DoIsVertexArrayOES(GLuint client_id); 1367 1368 // Wrapper for glLinkProgram 1369 void DoLinkProgram(GLuint program); 1370 1371 // Helper for RegisterSharedIdsCHROMIUM. 1372 void DoRegisterSharedIdsCHROMIUM( 1373 GLuint namespace_id, GLsizei n, const GLuint* ids); 1374 1375 // Wrapper for glRenderbufferStorage. 1376 void DoRenderbufferStorage( 1377 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 1378 1379 // Handler for glRenderbufferStorageMultisampleCHROMIUM. 1380 void DoRenderbufferStorageMultisampleCHROMIUM( 1381 GLenum target, GLsizei samples, GLenum internalformat, 1382 GLsizei width, GLsizei height); 1383 1384 // Handler for glRenderbufferStorageMultisampleEXT 1385 // (multisampled_render_to_texture). 1386 void DoRenderbufferStorageMultisampleEXT( 1387 GLenum target, GLsizei samples, GLenum internalformat, 1388 GLsizei width, GLsizei height); 1389 1390 // Common validation for multisample extensions. 1391 bool ValidateRenderbufferStorageMultisample(GLsizei samples, 1392 GLenum internalformat, 1393 GLsizei width, 1394 GLsizei height); 1395 1396 // Verifies that the currently bound multisample renderbuffer is valid 1397 // Very slow! Only done on platforms with driver bugs that return invalid 1398 // buffers under memory pressure 1399 bool VerifyMultisampleRenderbufferIntegrity( 1400 GLuint renderbuffer, GLenum format); 1401 1402 // Wrapper for glReleaseShaderCompiler. 1403 void DoReleaseShaderCompiler() { } 1404 1405 // Wrappers for glTexParameter functions. 1406 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); 1407 void DoTexParameteri(GLenum target, GLenum pname, GLint param); 1408 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); 1409 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); 1410 1411 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 1412 // spec only these 2 functions can be used to set sampler uniforms. 1413 void DoUniform1i(GLint fake_location, GLint v0); 1414 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value); 1415 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value); 1416 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value); 1417 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value); 1418 1419 // Wrappers for glUniformfv because some drivers don't correctly accept 1420 // bool uniforms. 1421 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value); 1422 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value); 1423 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value); 1424 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value); 1425 1426 void DoUniformMatrix2fv( 1427 GLint fake_location, GLsizei count, GLboolean transpose, 1428 const GLfloat* value); 1429 void DoUniformMatrix3fv( 1430 GLint fake_location, GLsizei count, GLboolean transpose, 1431 const GLfloat* value); 1432 void DoUniformMatrix4fv( 1433 GLint fake_location, GLsizei count, GLboolean transpose, 1434 const GLfloat* value); 1435 1436 bool SetVertexAttribValue( 1437 const char* function_name, GLuint index, const GLfloat* value); 1438 1439 // Wrappers for glVertexAttrib?? 1440 void DoVertexAttrib1f(GLuint index, GLfloat v0); 1441 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1); 1442 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2); 1443 void DoVertexAttrib4f( 1444 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 1445 void DoVertexAttrib1fv(GLuint index, const GLfloat *v); 1446 void DoVertexAttrib2fv(GLuint index, const GLfloat *v); 1447 void DoVertexAttrib3fv(GLuint index, const GLfloat *v); 1448 void DoVertexAttrib4fv(GLuint index, const GLfloat *v); 1449 1450 // Wrapper for glViewport 1451 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); 1452 1453 // Wrapper for glUseProgram 1454 void DoUseProgram(GLuint program); 1455 1456 // Wrapper for glValidateProgram. 1457 void DoValidateProgram(GLuint program_client_id); 1458 1459 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker); 1460 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group); 1461 void DoPopGroupMarkerEXT(void); 1462 1463 // Gets the number of values that will be returned by glGetXXX. Returns 1464 // false if pname is unknown. 1465 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); 1466 1467 // Checks if the current program and vertex attributes are valid for drawing. 1468 bool IsDrawValid( 1469 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount); 1470 1471 // Returns true if successful, simulated will be true if attrib0 was 1472 // simulated. 1473 bool SimulateAttrib0( 1474 const char* function_name, GLuint max_vertex_accessed, bool* simulated); 1475 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding); 1476 1477 // If an image is bound to texture, this will call Will/DidUseTexImage 1478 // if needed. 1479 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget); 1480 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget); 1481 1482 // Returns false if textures were replaced. 1483 bool PrepareTexturesForRender(); 1484 void RestoreStateForTextures(); 1485 1486 // Returns true if GL_FIXED attribs were simulated. 1487 bool SimulateFixedAttribs( 1488 const char* function_name, 1489 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount); 1490 void RestoreStateForSimulatedFixedAttribs(); 1491 1492 // Handle DrawArrays and DrawElements for both instanced and non-instanced 1493 // cases (primcount is 0 for non-instanced). 1494 error::Error DoDrawArrays( 1495 const char* function_name, 1496 bool instanced, GLenum mode, GLint first, GLsizei count, 1497 GLsizei primcount); 1498 error::Error DoDrawElements( 1499 const char* function_name, 1500 bool instanced, GLenum mode, GLsizei count, GLenum type, 1501 int32 offset, GLsizei primcount); 1502 1503 GLenum GetBindTargetForSamplerType(GLenum type) { 1504 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || 1505 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB); 1506 switch (type) { 1507 case GL_SAMPLER_2D: 1508 return GL_TEXTURE_2D; 1509 case GL_SAMPLER_CUBE: 1510 return GL_TEXTURE_CUBE_MAP; 1511 case GL_SAMPLER_EXTERNAL_OES: 1512 return GL_TEXTURE_EXTERNAL_OES; 1513 case GL_SAMPLER_2D_RECT_ARB: 1514 return GL_TEXTURE_RECTANGLE_ARB; 1515 } 1516 1517 NOTREACHED(); 1518 return 0; 1519 } 1520 1521 // Gets the framebuffer info for a particular target. 1522 Framebuffer* GetFramebufferInfoForTarget(GLenum target) { 1523 Framebuffer* framebuffer = NULL; 1524 switch (target) { 1525 case GL_FRAMEBUFFER: 1526 case GL_DRAW_FRAMEBUFFER_EXT: 1527 framebuffer = framebuffer_state_.bound_draw_framebuffer.get(); 1528 break; 1529 case GL_READ_FRAMEBUFFER_EXT: 1530 framebuffer = framebuffer_state_.bound_read_framebuffer.get(); 1531 break; 1532 default: 1533 NOTREACHED(); 1534 break; 1535 } 1536 return framebuffer; 1537 } 1538 1539 Renderbuffer* GetRenderbufferInfoForTarget( 1540 GLenum target) { 1541 Renderbuffer* renderbuffer = NULL; 1542 switch (target) { 1543 case GL_RENDERBUFFER: 1544 renderbuffer = state_.bound_renderbuffer.get(); 1545 break; 1546 default: 1547 NOTREACHED(); 1548 break; 1549 } 1550 return renderbuffer; 1551 } 1552 1553 // Validates the program and location for a glGetUniform call and returns 1554 // a SizeResult setup to receive the result. Returns true if glGetUniform 1555 // should be called. 1556 bool GetUniformSetup( 1557 GLuint program, GLint fake_location, 1558 uint32 shm_id, uint32 shm_offset, 1559 error::Error* error, GLint* real_location, GLuint* service_id, 1560 void** result, GLenum* result_type); 1561 1562 virtual bool WasContextLost() OVERRIDE; 1563 virtual bool WasContextLostByRobustnessExtension() OVERRIDE; 1564 virtual void LoseContext(uint32 reset_status) OVERRIDE; 1565 1566 #if defined(OS_MACOSX) 1567 void ReleaseIOSurfaceForTexture(GLuint texture_id); 1568 #endif 1569 1570 bool ValidateCompressedTexDimensions( 1571 const char* function_name, 1572 GLint level, GLsizei width, GLsizei height, GLenum format); 1573 bool ValidateCompressedTexFuncData( 1574 const char* function_name, 1575 GLsizei width, GLsizei height, GLenum format, size_t size); 1576 bool ValidateCompressedTexSubDimensions( 1577 const char* function_name, 1578 GLenum target, GLint level, GLint xoffset, GLint yoffset, 1579 GLsizei width, GLsizei height, GLenum format, 1580 Texture* texture); 1581 1582 void RenderWarning(const char* filename, int line, const std::string& msg); 1583 void PerformanceWarning( 1584 const char* filename, int line, const std::string& msg); 1585 1586 const FeatureInfo::FeatureFlags& features() const { 1587 return feature_info_->feature_flags(); 1588 } 1589 1590 const FeatureInfo::Workarounds& workarounds() const { 1591 return feature_info_->workarounds(); 1592 } 1593 1594 bool ShouldDeferDraws() { 1595 return !offscreen_target_frame_buffer_.get() && 1596 framebuffer_state_.bound_draw_framebuffer.get() == NULL && 1597 surface_->DeferDraws(); 1598 } 1599 1600 bool ShouldDeferReads() { 1601 return !offscreen_target_frame_buffer_.get() && 1602 framebuffer_state_.bound_read_framebuffer.get() == NULL && 1603 surface_->DeferDraws(); 1604 } 1605 1606 error::Error WillAccessBoundFramebufferForDraw() { 1607 if (ShouldDeferDraws()) 1608 return error::kDeferCommandUntilLater; 1609 if (!offscreen_target_frame_buffer_.get() && 1610 !framebuffer_state_.bound_draw_framebuffer.get() && 1611 !surface_->SetBackbufferAllocation(true)) 1612 return error::kLostContext; 1613 return error::kNoError; 1614 } 1615 1616 error::Error WillAccessBoundFramebufferForRead() { 1617 if (ShouldDeferReads()) 1618 return error::kDeferCommandUntilLater; 1619 if (!offscreen_target_frame_buffer_.get() && 1620 !framebuffer_state_.bound_read_framebuffer.get() && 1621 !surface_->SetBackbufferAllocation(true)) 1622 return error::kLostContext; 1623 return error::kNoError; 1624 } 1625 1626 void ProcessPendingReadPixels(); 1627 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer); 1628 1629 // Generate a member function prototype for each command in an automated and 1630 // typesafe way. 1631 #define GLES2_CMD_OP(name) \ 1632 Error Handle ## name( \ 1633 uint32 immediate_data_size, \ 1634 const cmds::name& args); \ 1635 1636 GLES2_COMMAND_LIST(GLES2_CMD_OP) 1637 1638 #undef GLES2_CMD_OP 1639 1640 // The GL context this decoder renders to on behalf of the client. 1641 scoped_refptr<gfx::GLSurface> surface_; 1642 scoped_refptr<gfx::GLContext> context_; 1643 1644 // The ContextGroup for this decoder uses to track resources. 1645 scoped_refptr<ContextGroup> group_; 1646 1647 DebugMarkerManager debug_marker_manager_; 1648 Logger logger_; 1649 1650 // All the state for this context. 1651 ContextState state_; 1652 1653 // Current width and height of the offscreen frame buffer. 1654 gfx::Size offscreen_size_; 1655 1656 // Util to help with GL. 1657 GLES2Util util_; 1658 1659 // unpack flip y as last set by glPixelStorei 1660 bool unpack_flip_y_; 1661 1662 // unpack (un)premultiply alpha as last set by glPixelStorei 1663 bool unpack_premultiply_alpha_; 1664 bool unpack_unpremultiply_alpha_; 1665 1666 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not). 1667 GLuint attrib_0_buffer_id_; 1668 1669 // The value currently in attrib_0. 1670 Vec4 attrib_0_value_; 1671 1672 // Whether or not the attrib_0 buffer holds the attrib_0_value. 1673 bool attrib_0_buffer_matches_value_; 1674 1675 // The size of attrib 0. 1676 GLsizei attrib_0_size_; 1677 1678 // The buffer used to simulate GL_FIXED attribs. 1679 GLuint fixed_attrib_buffer_id_; 1680 1681 // The size of fiixed attrib buffer. 1682 GLsizei fixed_attrib_buffer_size_; 1683 1684 // The offscreen frame buffer that the client renders to. With EGL, the 1685 // depth and stencil buffers are separate. With regular GL there is a single 1686 // packed depth stencil buffer in offscreen_target_depth_render_buffer_. 1687 // offscreen_target_stencil_render_buffer_ is unused. 1688 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_; 1689 scoped_ptr<BackTexture> offscreen_target_color_texture_; 1690 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_; 1691 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_; 1692 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_; 1693 GLenum offscreen_target_color_format_; 1694 GLenum offscreen_target_depth_format_; 1695 GLenum offscreen_target_stencil_format_; 1696 GLsizei offscreen_target_samples_; 1697 GLboolean offscreen_target_buffer_preserved_; 1698 1699 // The copy that is saved when SwapBuffers is called. 1700 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_; 1701 scoped_ptr<BackTexture> offscreen_saved_color_texture_; 1702 scoped_refptr<TextureRef> 1703 offscreen_saved_color_texture_info_; 1704 1705 // The copy that is used as the destination for multi-sample resolves. 1706 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_; 1707 scoped_ptr<BackTexture> offscreen_resolved_color_texture_; 1708 GLenum offscreen_saved_color_format_; 1709 1710 scoped_ptr<QueryManager> query_manager_; 1711 1712 scoped_ptr<VertexArrayManager> vertex_array_manager_; 1713 1714 base::Callback<void(gfx::Size, float)> resize_callback_; 1715 1716 WaitSyncPointCallback wait_sync_point_callback_; 1717 1718 ShaderCacheCallback shader_cache_callback_; 1719 1720 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_; 1721 1722 // The format of the back buffer_ 1723 GLenum back_buffer_color_format_; 1724 bool back_buffer_has_depth_; 1725 bool back_buffer_has_stencil_; 1726 1727 // Backbuffer attachments that are currently undefined. 1728 uint32 backbuffer_needs_clear_bits_; 1729 1730 // The current decoder error communicates the decoder error through command 1731 // processing functions that do not return the error value. Should be set only 1732 // if not returning an error. 1733 error::Error current_decoder_error_; 1734 1735 bool use_shader_translator_; 1736 scoped_refptr<ShaderTranslator> vertex_translator_; 1737 scoped_refptr<ShaderTranslator> fragment_translator_; 1738 1739 DisallowedFeatures disallowed_features_; 1740 1741 // Cached from ContextGroup 1742 const Validators* validators_; 1743 scoped_refptr<FeatureInfo> feature_info_; 1744 1745 int frame_number_; 1746 1747 bool has_robustness_extension_; 1748 GLenum reset_status_; 1749 bool reset_by_robustness_extension_; 1750 bool supports_post_sub_buffer_; 1751 1752 // These flags are used to override the state of the shared feature_info_ 1753 // member. Because the same FeatureInfo instance may be shared among many 1754 // contexts, the assumptions on the availablity of extensions in WebGL 1755 // contexts may be broken. These flags override the shared state to preserve 1756 // WebGL semantics. 1757 bool force_webgl_glsl_validation_; 1758 bool derivatives_explicitly_enabled_; 1759 bool frag_depth_explicitly_enabled_; 1760 bool draw_buffers_explicitly_enabled_; 1761 bool shader_texture_lod_explicitly_enabled_; 1762 1763 bool compile_shader_always_succeeds_; 1764 1765 // An optional behaviour to lose the context and group when OOM. 1766 bool lose_context_when_out_of_memory_; 1767 1768 // Log extra info. 1769 bool service_logging_; 1770 1771 #if defined(OS_MACOSX) 1772 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap; 1773 TextureToIOSurfaceMap texture_to_io_surface_map_; 1774 #endif 1775 1776 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; 1777 1778 // Cached values of the currently assigned viewport dimensions. 1779 GLsizei viewport_max_width_; 1780 GLsizei viewport_max_height_; 1781 1782 // Command buffer stats. 1783 base::TimeDelta total_processing_commands_time_; 1784 1785 // States related to each manager. 1786 DecoderTextureState texture_state_; 1787 DecoderFramebufferState framebuffer_state_; 1788 1789 scoped_ptr<GPUTracer> gpu_tracer_; 1790 scoped_ptr<GPUStateTracer> gpu_state_tracer_; 1791 int gpu_trace_level_; 1792 bool gpu_trace_commands_; 1793 1794 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_; 1795 1796 // Used to validate multisample renderbuffers if needed 1797 GLuint validation_texture_; 1798 GLuint validation_fbo_multisample_; 1799 GLuint validation_fbo_; 1800 1801 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); 1802 }; 1803 1804 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor( 1805 const char* function_name, ErrorState* error_state) 1806 : function_name_(function_name), 1807 error_state_(error_state) { 1808 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_); 1809 } 1810 1811 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { 1812 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_); 1813 } 1814 1815 static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) { 1816 TextureUnit& info = state->texture_units[0]; 1817 GLuint last_id; 1818 scoped_refptr<TextureRef> texture_ref; 1819 switch (target) { 1820 case GL_TEXTURE_2D: 1821 texture_ref = info.bound_texture_2d; 1822 break; 1823 case GL_TEXTURE_CUBE_MAP: 1824 texture_ref = info.bound_texture_cube_map; 1825 break; 1826 case GL_TEXTURE_EXTERNAL_OES: 1827 texture_ref = info.bound_texture_external_oes; 1828 break; 1829 case GL_TEXTURE_RECTANGLE_ARB: 1830 texture_ref = info.bound_texture_rectangle_arb; 1831 break; 1832 default: 1833 NOTREACHED(); 1834 break; 1835 } 1836 if (texture_ref.get()) { 1837 last_id = texture_ref->service_id(); 1838 } else { 1839 last_id = 0; 1840 } 1841 1842 glBindTexture(target, last_id); 1843 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit); 1844 } 1845 1846 ScopedTextureBinder::ScopedTextureBinder(ContextState* state, 1847 GLuint id, 1848 GLenum target) 1849 : state_(state), 1850 target_(target) { 1851 ScopedGLErrorSuppressor suppressor( 1852 "ScopedTextureBinder::ctor", state_->GetErrorState()); 1853 1854 // TODO(apatrick): Check if there are any other states that need to be reset 1855 // before binding a new texture. 1856 glActiveTexture(GL_TEXTURE0); 1857 glBindTexture(target, id); 1858 } 1859 1860 ScopedTextureBinder::~ScopedTextureBinder() { 1861 ScopedGLErrorSuppressor suppressor( 1862 "ScopedTextureBinder::dtor", state_->GetErrorState()); 1863 RestoreCurrentTextureBindings(state_, target_); 1864 } 1865 1866 ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state, 1867 GLuint id) 1868 : state_(state) { 1869 ScopedGLErrorSuppressor suppressor( 1870 "ScopedRenderBufferBinder::ctor", state_->GetErrorState()); 1871 glBindRenderbufferEXT(GL_RENDERBUFFER, id); 1872 } 1873 1874 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { 1875 ScopedGLErrorSuppressor suppressor( 1876 "ScopedRenderBufferBinder::dtor", state_->GetErrorState()); 1877 state_->RestoreRenderbufferBindings(); 1878 } 1879 1880 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, 1881 GLuint id) 1882 : decoder_(decoder) { 1883 ScopedGLErrorSuppressor suppressor( 1884 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState()); 1885 glBindFramebufferEXT(GL_FRAMEBUFFER, id); 1886 decoder->OnFboChanged(); 1887 } 1888 1889 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { 1890 ScopedGLErrorSuppressor suppressor( 1891 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState()); 1892 decoder_->RestoreCurrentFramebufferBindings(); 1893 } 1894 1895 ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( 1896 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) 1897 : decoder_(decoder) { 1898 resolve_and_bind_ = ( 1899 decoder_->offscreen_target_frame_buffer_.get() && 1900 decoder_->IsOffscreenBufferMultisampled() && 1901 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() || 1902 enforce_internal_framebuffer)); 1903 if (!resolve_and_bind_) 1904 return; 1905 1906 ScopedGLErrorSuppressor suppressor( 1907 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState()); 1908 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 1909 decoder_->offscreen_target_frame_buffer_->id()); 1910 GLuint targetid; 1911 if (internal) { 1912 if (!decoder_->offscreen_resolved_frame_buffer_.get()) { 1913 decoder_->offscreen_resolved_frame_buffer_.reset( 1914 new BackFramebuffer(decoder_)); 1915 decoder_->offscreen_resolved_frame_buffer_->Create(); 1916 decoder_->offscreen_resolved_color_texture_.reset( 1917 new BackTexture(decoder->memory_tracker(), &decoder->state_)); 1918 decoder_->offscreen_resolved_color_texture_->Create(); 1919 1920 DCHECK(decoder_->offscreen_saved_color_format_); 1921 decoder_->offscreen_resolved_color_texture_->AllocateStorage( 1922 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_, 1923 false); 1924 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture( 1925 decoder_->offscreen_resolved_color_texture_.get()); 1926 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() != 1927 GL_FRAMEBUFFER_COMPLETE) { 1928 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed " 1929 << "because offscreen resolved FBO was incomplete."; 1930 return; 1931 } 1932 } 1933 targetid = decoder_->offscreen_resolved_frame_buffer_->id(); 1934 } else { 1935 targetid = decoder_->offscreen_saved_frame_buffer_->id(); 1936 } 1937 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid); 1938 const int width = decoder_->offscreen_size_.width(); 1939 const int height = decoder_->offscreen_size_.height(); 1940 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 1941 decoder->BlitFramebufferHelper(0, 1942 0, 1943 width, 1944 height, 1945 0, 1946 0, 1947 width, 1948 height, 1949 GL_COLOR_BUFFER_BIT, 1950 GL_NEAREST); 1951 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); 1952 } 1953 1954 ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { 1955 if (!resolve_and_bind_) 1956 return; 1957 1958 ScopedGLErrorSuppressor suppressor( 1959 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState()); 1960 decoder_->RestoreCurrentFramebufferBindings(); 1961 if (decoder_->state_.enable_flags.scissor_test) { 1962 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); 1963 } 1964 } 1965 1966 BackTexture::BackTexture( 1967 MemoryTracker* memory_tracker, 1968 ContextState* state) 1969 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged), 1970 state_(state), 1971 bytes_allocated_(0), 1972 id_(0) { 1973 } 1974 1975 BackTexture::~BackTexture() { 1976 // This does not destroy the render texture because that would require that 1977 // the associated GL context was current. Just check that it was explicitly 1978 // destroyed. 1979 DCHECK_EQ(id_, 0u); 1980 } 1981 1982 void BackTexture::Create() { 1983 ScopedGLErrorSuppressor suppressor("BackTexture::Create", 1984 state_->GetErrorState()); 1985 Destroy(); 1986 glGenTextures(1, &id_); 1987 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); 1988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1990 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1992 1993 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is 1994 // never called on an offscreen context, no data will ever be uploaded to the 1995 // saved offscreen color texture (it is deferred until to when SwapBuffers 1996 // is called). My idea is that some nvidia drivers might have a bug where 1997 // deleting a texture that has never been populated might cause a 1998 // crash. 1999 glTexImage2D( 2000 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 2001 2002 bytes_allocated_ = 16u * 16u * 4u; 2003 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2004 } 2005 2006 bool BackTexture::AllocateStorage( 2007 const gfx::Size& size, GLenum format, bool zero) { 2008 DCHECK_NE(id_, 0u); 2009 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", 2010 state_->GetErrorState()); 2011 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); 2012 uint32 image_size = 0; 2013 GLES2Util::ComputeImageDataSizes( 2014 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size, 2015 NULL, NULL); 2016 2017 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) { 2018 return false; 2019 } 2020 2021 scoped_ptr<char[]> zero_data; 2022 if (zero) { 2023 zero_data.reset(new char[image_size]); 2024 memset(zero_data.get(), 0, image_size); 2025 } 2026 2027 glTexImage2D(GL_TEXTURE_2D, 2028 0, // mip level 2029 format, 2030 size.width(), 2031 size.height(), 2032 0, // border 2033 format, 2034 GL_UNSIGNED_BYTE, 2035 zero_data.get()); 2036 2037 size_ = size; 2038 2039 bool success = glGetError() == GL_NO_ERROR; 2040 if (success) { 2041 memory_tracker_.TrackMemFree(bytes_allocated_); 2042 bytes_allocated_ = image_size; 2043 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2044 } 2045 return success; 2046 } 2047 2048 void BackTexture::Copy(const gfx::Size& size, GLenum format) { 2049 DCHECK_NE(id_, 0u); 2050 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", 2051 state_->GetErrorState()); 2052 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D); 2053 glCopyTexImage2D(GL_TEXTURE_2D, 2054 0, // level 2055 format, 2056 0, 0, 2057 size.width(), 2058 size.height(), 2059 0); // border 2060 } 2061 2062 void BackTexture::Destroy() { 2063 if (id_ != 0) { 2064 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", 2065 state_->GetErrorState()); 2066 glDeleteTextures(1, &id_); 2067 id_ = 0; 2068 } 2069 memory_tracker_.TrackMemFree(bytes_allocated_); 2070 bytes_allocated_ = 0; 2071 } 2072 2073 void BackTexture::Invalidate() { 2074 id_ = 0; 2075 } 2076 2077 BackRenderbuffer::BackRenderbuffer( 2078 RenderbufferManager* renderbuffer_manager, 2079 MemoryTracker* memory_tracker, 2080 ContextState* state) 2081 : renderbuffer_manager_(renderbuffer_manager), 2082 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged), 2083 state_(state), 2084 bytes_allocated_(0), 2085 id_(0) { 2086 } 2087 2088 BackRenderbuffer::~BackRenderbuffer() { 2089 // This does not destroy the render buffer because that would require that 2090 // the associated GL context was current. Just check that it was explicitly 2091 // destroyed. 2092 DCHECK_EQ(id_, 0u); 2093 } 2094 2095 void BackRenderbuffer::Create() { 2096 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", 2097 state_->GetErrorState()); 2098 Destroy(); 2099 glGenRenderbuffersEXT(1, &id_); 2100 } 2101 2102 bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info, 2103 const gfx::Size& size, 2104 GLenum format, 2105 GLsizei samples) { 2106 ScopedGLErrorSuppressor suppressor( 2107 "BackRenderbuffer::AllocateStorage", state_->GetErrorState()); 2108 ScopedRenderBufferBinder binder(state_, id_); 2109 2110 uint32 estimated_size = 0; 2111 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize( 2112 size.width(), size.height(), samples, format, &estimated_size)) { 2113 return false; 2114 } 2115 2116 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) { 2117 return false; 2118 } 2119 2120 if (samples <= 1) { 2121 glRenderbufferStorageEXT(GL_RENDERBUFFER, 2122 format, 2123 size.width(), 2124 size.height()); 2125 } else { 2126 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info, 2127 GL_RENDERBUFFER, 2128 samples, 2129 format, 2130 size.width(), 2131 size.height()); 2132 } 2133 bool success = glGetError() == GL_NO_ERROR; 2134 if (success) { 2135 // Mark the previously allocated bytes as free. 2136 memory_tracker_.TrackMemFree(bytes_allocated_); 2137 bytes_allocated_ = estimated_size; 2138 // Track the newly allocated bytes. 2139 memory_tracker_.TrackMemAlloc(bytes_allocated_); 2140 } 2141 return success; 2142 } 2143 2144 void BackRenderbuffer::Destroy() { 2145 if (id_ != 0) { 2146 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", 2147 state_->GetErrorState()); 2148 glDeleteRenderbuffersEXT(1, &id_); 2149 id_ = 0; 2150 } 2151 memory_tracker_.TrackMemFree(bytes_allocated_); 2152 bytes_allocated_ = 0; 2153 } 2154 2155 void BackRenderbuffer::Invalidate() { 2156 id_ = 0; 2157 } 2158 2159 BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder) 2160 : decoder_(decoder), 2161 id_(0) { 2162 } 2163 2164 BackFramebuffer::~BackFramebuffer() { 2165 // This does not destroy the frame buffer because that would require that 2166 // the associated GL context was current. Just check that it was explicitly 2167 // destroyed. 2168 DCHECK_EQ(id_, 0u); 2169 } 2170 2171 void BackFramebuffer::Create() { 2172 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", 2173 decoder_->GetErrorState()); 2174 Destroy(); 2175 glGenFramebuffersEXT(1, &id_); 2176 } 2177 2178 void BackFramebuffer::AttachRenderTexture(BackTexture* texture) { 2179 DCHECK_NE(id_, 0u); 2180 ScopedGLErrorSuppressor suppressor( 2181 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState()); 2182 ScopedFrameBufferBinder binder(decoder_, id_); 2183 GLuint attach_id = texture ? texture->id() : 0; 2184 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 2185 GL_COLOR_ATTACHMENT0, 2186 GL_TEXTURE_2D, 2187 attach_id, 2188 0); 2189 } 2190 2191 void BackFramebuffer::AttachRenderBuffer(GLenum target, 2192 BackRenderbuffer* render_buffer) { 2193 DCHECK_NE(id_, 0u); 2194 ScopedGLErrorSuppressor suppressor( 2195 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState()); 2196 ScopedFrameBufferBinder binder(decoder_, id_); 2197 GLuint attach_id = render_buffer ? render_buffer->id() : 0; 2198 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, 2199 target, 2200 GL_RENDERBUFFER, 2201 attach_id); 2202 } 2203 2204 void BackFramebuffer::Destroy() { 2205 if (id_ != 0) { 2206 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", 2207 decoder_->GetErrorState()); 2208 glDeleteFramebuffersEXT(1, &id_); 2209 id_ = 0; 2210 } 2211 } 2212 2213 void BackFramebuffer::Invalidate() { 2214 id_ = 0; 2215 } 2216 2217 GLenum BackFramebuffer::CheckStatus() { 2218 DCHECK_NE(id_, 0u); 2219 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", 2220 decoder_->GetErrorState()); 2221 ScopedFrameBufferBinder binder(decoder_, id_); 2222 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 2223 } 2224 2225 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { 2226 return new GLES2DecoderImpl(group); 2227 } 2228 2229 GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) 2230 : GLES2Decoder(), 2231 group_(group), 2232 logger_(&debug_marker_manager_), 2233 state_(group_->feature_info(), this, &logger_), 2234 unpack_flip_y_(false), 2235 unpack_premultiply_alpha_(false), 2236 unpack_unpremultiply_alpha_(false), 2237 attrib_0_buffer_id_(0), 2238 attrib_0_buffer_matches_value_(true), 2239 attrib_0_size_(0), 2240 fixed_attrib_buffer_id_(0), 2241 fixed_attrib_buffer_size_(0), 2242 offscreen_target_color_format_(0), 2243 offscreen_target_depth_format_(0), 2244 offscreen_target_stencil_format_(0), 2245 offscreen_target_samples_(0), 2246 offscreen_target_buffer_preserved_(true), 2247 offscreen_saved_color_format_(0), 2248 back_buffer_color_format_(0), 2249 back_buffer_has_depth_(false), 2250 back_buffer_has_stencil_(false), 2251 backbuffer_needs_clear_bits_(0), 2252 current_decoder_error_(error::kNoError), 2253 use_shader_translator_(true), 2254 validators_(group_->feature_info()->validators()), 2255 feature_info_(group_->feature_info()), 2256 frame_number_(0), 2257 has_robustness_extension_(false), 2258 reset_status_(GL_NO_ERROR), 2259 reset_by_robustness_extension_(false), 2260 supports_post_sub_buffer_(false), 2261 force_webgl_glsl_validation_(false), 2262 derivatives_explicitly_enabled_(false), 2263 frag_depth_explicitly_enabled_(false), 2264 draw_buffers_explicitly_enabled_(false), 2265 shader_texture_lod_explicitly_enabled_(false), 2266 compile_shader_always_succeeds_(false), 2267 lose_context_when_out_of_memory_(false), 2268 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch( 2269 switches::kEnableGPUServiceLoggingGPU)), 2270 viewport_max_width_(0), 2271 viewport_max_height_(0), 2272 texture_state_(group_->feature_info() 2273 ->workarounds() 2274 .texsubimage2d_faster_than_teximage2d), 2275 validation_texture_(0), 2276 validation_fbo_multisample_(0), 2277 validation_fbo_(0) { 2278 DCHECK(group); 2279 2280 attrib_0_value_.v[0] = 0.0f; 2281 attrib_0_value_.v[1] = 0.0f; 2282 attrib_0_value_.v[2] = 0.0f; 2283 attrib_0_value_.v[3] = 1.0f; 2284 2285 // The shader translator is used for WebGL even when running on EGL 2286 // because additional restrictions are needed (like only enabling 2287 // GL_OES_standard_derivatives on demand). It is used for the unit 2288 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes 2289 // the empty string to CompileShader and this is not a valid shader. 2290 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL || 2291 CommandLine::ForCurrentProcess()->HasSwitch( 2292 switches::kDisableGLSLTranslator)) { 2293 use_shader_translator_ = false; 2294 } 2295 } 2296 2297 GLES2DecoderImpl::~GLES2DecoderImpl() { 2298 } 2299 2300 bool GLES2DecoderImpl::Initialize( 2301 const scoped_refptr<gfx::GLSurface>& surface, 2302 const scoped_refptr<gfx::GLContext>& context, 2303 bool offscreen, 2304 const gfx::Size& size, 2305 const DisallowedFeatures& disallowed_features, 2306 const std::vector<int32>& attribs) { 2307 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); 2308 DCHECK(context->IsCurrent(surface.get())); 2309 DCHECK(!context_.get()); 2310 2311 set_initialized(); 2312 gpu_tracer_ = GPUTracer::Create(this); 2313 gpu_state_tracer_ = GPUStateTracer::Create(&state_); 2314 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime 2315 gpu_trace_level_ = 2; 2316 gpu_trace_commands_ = false; 2317 2318 if (CommandLine::ForCurrentProcess()->HasSwitch( 2319 switches::kEnableGPUDebugging)) { 2320 set_debug(true); 2321 } 2322 2323 if (CommandLine::ForCurrentProcess()->HasSwitch( 2324 switches::kEnableGPUCommandLogging)) { 2325 set_log_commands(true); 2326 } 2327 2328 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch( 2329 switches::kCompileShaderAlwaysSucceeds); 2330 2331 2332 // Take ownership of the context and surface. The surface can be replaced with 2333 // SetSurface. 2334 context_ = context; 2335 surface_ = surface; 2336 2337 ContextCreationAttribHelper attrib_parser; 2338 if (!attrib_parser.Parse(attribs)) 2339 return false; 2340 2341 // Save the loseContextWhenOutOfMemory context creation attribute. 2342 lose_context_when_out_of_memory_ = 2343 attrib_parser.lose_context_when_out_of_memory_; 2344 2345 // If the failIfMajorPerformanceCaveat context creation attribute was true 2346 // and we are using a software renderer, fail. 2347 if (attrib_parser.fail_if_major_perf_caveat_ && 2348 feature_info_->feature_flags().is_swiftshader) { 2349 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. 2350 Destroy(true); 2351 return false; 2352 } 2353 2354 if (!group_->Initialize(this, disallowed_features)) { 2355 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " 2356 << "failed to initialize."; 2357 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. 2358 Destroy(true); 2359 return false; 2360 } 2361 CHECK_GL_ERROR(); 2362 2363 disallowed_features_ = disallowed_features; 2364 2365 state_.attrib_values.resize(group_->max_vertex_attribs()); 2366 vertex_array_manager_.reset(new VertexArrayManager()); 2367 2368 GLuint default_vertex_attrib_service_id = 0; 2369 if (features().native_vertex_array_object) { 2370 glGenVertexArraysOES(1, &default_vertex_attrib_service_id); 2371 glBindVertexArrayOES(default_vertex_attrib_service_id); 2372 } 2373 2374 state_.default_vertex_attrib_manager = 2375 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false); 2376 2377 state_.default_vertex_attrib_manager->Initialize( 2378 group_->max_vertex_attribs(), 2379 feature_info_->workarounds().init_vertex_attributes); 2380 2381 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call 2382 DoBindVertexArrayOES(0); 2383 2384 query_manager_.reset(new QueryManager(this, feature_info_.get())); 2385 2386 util_.set_num_compressed_texture_formats( 2387 validators_->compressed_texture_format.GetValues().size()); 2388 2389 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2390 // We have to enable vertex array 0 on OpenGL or it won't render. Note that 2391 // OpenGL ES 2.0 does not have this issue. 2392 glEnableVertexAttribArray(0); 2393 } 2394 glGenBuffersARB(1, &attrib_0_buffer_id_); 2395 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 2396 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); 2397 glBindBuffer(GL_ARRAY_BUFFER, 0); 2398 glGenBuffersARB(1, &fixed_attrib_buffer_id_); 2399 2400 state_.texture_units.resize(group_->max_texture_units()); 2401 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) { 2402 glActiveTexture(GL_TEXTURE0 + tt); 2403 // We want the last bind to be 2D. 2404 TextureRef* ref; 2405 if (features().oes_egl_image_external) { 2406 ref = texture_manager()->GetDefaultTextureInfo( 2407 GL_TEXTURE_EXTERNAL_OES); 2408 state_.texture_units[tt].bound_texture_external_oes = ref; 2409 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0); 2410 } 2411 if (features().arb_texture_rectangle) { 2412 ref = texture_manager()->GetDefaultTextureInfo( 2413 GL_TEXTURE_RECTANGLE_ARB); 2414 state_.texture_units[tt].bound_texture_rectangle_arb = ref; 2415 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0); 2416 } 2417 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP); 2418 state_.texture_units[tt].bound_texture_cube_map = ref; 2419 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0); 2420 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); 2421 state_.texture_units[tt].bound_texture_2d = ref; 2422 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0); 2423 } 2424 glActiveTexture(GL_TEXTURE0); 2425 CHECK_GL_ERROR(); 2426 2427 if (offscreen) { 2428 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 && 2429 features().chromium_framebuffer_multisample) { 2430 // Per ext_framebuffer_multisample spec, need max bound on sample count. 2431 // max_sample_count must be initialized to a sane value. If 2432 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. 2433 GLint max_sample_count = 1; 2434 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); 2435 offscreen_target_samples_ = std::min(attrib_parser.samples_, 2436 max_sample_count); 2437 } else { 2438 offscreen_target_samples_ = 1; 2439 } 2440 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_; 2441 2442 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 2443 const bool rgb8_supported = 2444 context_->HasExtension("GL_OES_rgb8_rgba8"); 2445 // The only available default render buffer formats in GLES2 have very 2446 // little precision. Don't enable multisampling unless 8-bit render 2447 // buffer formats are available--instead fall back to 8-bit textures. 2448 if (rgb8_supported && offscreen_target_samples_ > 1) { 2449 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2450 GL_RGBA8 : GL_RGB8; 2451 } else { 2452 offscreen_target_samples_ = 1; 2453 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2454 GL_RGBA : GL_RGB; 2455 } 2456 2457 // ANGLE only supports packed depth/stencil formats, so use it if it is 2458 // available. 2459 const bool depth24_stencil8_supported = 2460 feature_info_->feature_flags().packed_depth24_stencil8; 2461 VLOG(1) << "GL_OES_packed_depth_stencil " 2462 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2463 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && 2464 depth24_stencil8_supported) { 2465 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2466 offscreen_target_stencil_format_ = 0; 2467 } else { 2468 // It may be the case that this depth/stencil combination is not 2469 // supported, but this will be checked later by CheckFramebufferStatus. 2470 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ? 2471 GL_DEPTH_COMPONENT16 : 0; 2472 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ? 2473 GL_STENCIL_INDEX8 : 0; 2474 } 2475 } else { 2476 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2477 GL_RGBA : GL_RGB; 2478 2479 // If depth is requested at all, use the packed depth stencil format if 2480 // it's available, as some desktop GL drivers don't support any non-packed 2481 // formats for depth attachments. 2482 const bool depth24_stencil8_supported = 2483 feature_info_->feature_flags().packed_depth24_stencil8; 2484 VLOG(1) << "GL_EXT_packed_depth_stencil " 2485 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2486 2487 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && 2488 depth24_stencil8_supported) { 2489 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2490 offscreen_target_stencil_format_ = 0; 2491 } else { 2492 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ? 2493 GL_DEPTH_COMPONENT : 0; 2494 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ? 2495 GL_STENCIL_INDEX : 0; 2496 } 2497 } 2498 2499 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ? 2500 GL_RGBA : GL_RGB; 2501 2502 // Create the target frame buffer. This is the one that the client renders 2503 // directly to. 2504 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this)); 2505 offscreen_target_frame_buffer_->Create(); 2506 // Due to GLES2 format limitations, either the color texture (for 2507 // non-multisampling) or the color render buffer (for multisampling) will be 2508 // attached to the offscreen frame buffer. The render buffer has more 2509 // limited formats available to it, but the texture can't do multisampling. 2510 if (IsOffscreenBufferMultisampled()) { 2511 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer( 2512 renderbuffer_manager(), memory_tracker(), &state_)); 2513 offscreen_target_color_render_buffer_->Create(); 2514 } else { 2515 offscreen_target_color_texture_.reset(new BackTexture( 2516 memory_tracker(), &state_)); 2517 offscreen_target_color_texture_->Create(); 2518 } 2519 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer( 2520 renderbuffer_manager(), memory_tracker(), &state_)); 2521 offscreen_target_depth_render_buffer_->Create(); 2522 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer( 2523 renderbuffer_manager(), memory_tracker(), &state_)); 2524 offscreen_target_stencil_render_buffer_->Create(); 2525 2526 // Create the saved offscreen texture. The target frame buffer is copied 2527 // here when SwapBuffers is called. 2528 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this)); 2529 offscreen_saved_frame_buffer_->Create(); 2530 // 2531 offscreen_saved_color_texture_.reset(new BackTexture( 2532 memory_tracker(), &state_)); 2533 offscreen_saved_color_texture_->Create(); 2534 2535 // Allocate the render buffers at their initial size and check the status 2536 // of the frame buffers is okay. 2537 if (!ResizeOffscreenFrameBuffer(size)) { 2538 LOG(ERROR) << "Could not allocate offscreen buffer storage."; 2539 Destroy(true); 2540 return false; 2541 } 2542 2543 // Allocate the offscreen saved color texture. 2544 DCHECK(offscreen_saved_color_format_); 2545 offscreen_saved_color_texture_->AllocateStorage( 2546 gfx::Size(1, 1), offscreen_saved_color_format_, true); 2547 2548 offscreen_saved_frame_buffer_->AttachRenderTexture( 2549 offscreen_saved_color_texture_.get()); 2550 if (offscreen_saved_frame_buffer_->CheckStatus() != 2551 GL_FRAMEBUFFER_COMPLETE) { 2552 LOG(ERROR) << "Offscreen saved FBO was incomplete."; 2553 Destroy(true); 2554 return false; 2555 } 2556 2557 // Bind to the new default frame buffer (the offscreen target frame buffer). 2558 // This should now be associated with ID zero. 2559 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2560 } else { 2561 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId()); 2562 // These are NOT if the back buffer has these proprorties. They are 2563 // if we want the command buffer to enforce them regardless of what 2564 // the real backbuffer is assuming the real back buffer gives us more than 2565 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll 2566 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we 2567 // can't do anything about that. 2568 2569 GLint v = 0; 2570 glGetIntegerv(GL_ALPHA_BITS, &v); 2571 // This checks if the user requested RGBA and we have RGBA then RGBA. If the 2572 // user requested RGB then RGB. If the user did not specify a preference 2573 // than use whatever we were given. Same for DEPTH and STENCIL. 2574 back_buffer_color_format_ = 2575 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB; 2576 glGetIntegerv(GL_DEPTH_BITS, &v); 2577 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0; 2578 glGetIntegerv(GL_STENCIL_BITS, &v); 2579 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0; 2580 } 2581 2582 // OpenGL ES 2.0 implicitly enables the desktop GL capability 2583 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact 2584 // isn't well documented; it was discovered in the Khronos OpenGL ES 2585 // mailing list archives. It also implicitly enables the desktop GL 2586 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord 2587 // variable in fragment shaders. 2588 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2589 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); 2590 glEnable(GL_POINT_SPRITE); 2591 } 2592 2593 has_robustness_extension_ = 2594 context->HasExtension("GL_ARB_robustness") || 2595 context->HasExtension("GL_EXT_robustness"); 2596 2597 if (!InitializeShaderTranslator()) { 2598 return false; 2599 } 2600 2601 state_.viewport_width = size.width(); 2602 state_.viewport_height = size.height(); 2603 2604 GLint viewport_params[4] = { 0 }; 2605 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); 2606 viewport_max_width_ = viewport_params[0]; 2607 viewport_max_height_ = viewport_params[1]; 2608 2609 state_.scissor_width = state_.viewport_width; 2610 state_.scissor_height = state_.viewport_height; 2611 2612 // Set all the default state because some GL drivers get it wrong. 2613 state_.InitCapabilities(NULL); 2614 state_.InitState(NULL); 2615 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 2616 2617 DoBindBuffer(GL_ARRAY_BUFFER, 0); 2618 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2619 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2620 DoBindRenderbuffer(GL_RENDERBUFFER, 0); 2621 2622 bool call_gl_clear = true; 2623 #if defined(OS_ANDROID) 2624 // Temporary workaround for Android WebView because this clear ignores the 2625 // clip and corrupts that external UI of the App. Not calling glClear is ok 2626 // because the system already clears the buffer before each draw. Proper 2627 // fix might be setting the scissor clip properly before initialize. See 2628 // crbug.com/259023 for details. 2629 call_gl_clear = surface_->GetHandle(); 2630 #endif 2631 if (call_gl_clear) { 2632 // Clear the backbuffer. 2633 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2634 } 2635 2636 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer(); 2637 if (feature_info_->workarounds() 2638 .disable_post_sub_buffers_for_onscreen_surfaces && 2639 !surface->IsOffscreen()) 2640 supports_post_sub_buffer_ = false; 2641 2642 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { 2643 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 2644 } 2645 2646 if (feature_info_->workarounds().unbind_fbo_on_context_switch) { 2647 context_->SetUnbindFboOnMakeCurrent(); 2648 } 2649 2650 if (feature_info_->workarounds().release_image_after_use) { 2651 image_manager()->SetReleaseAfterUse(); 2652 } 2653 2654 // Only compositor contexts are known to use only the subset of GL 2655 // that can be safely migrated between the iGPU and the dGPU. Mark 2656 // those contexts as safe to forcibly transition between the GPUs. 2657 // http://crbug.com/180876, http://crbug.com/227228 2658 if (!offscreen) 2659 context_->SetSafeToForceGpuSwitch(); 2660 2661 async_pixel_transfer_manager_.reset( 2662 AsyncPixelTransferManager::Create(context.get())); 2663 async_pixel_transfer_manager_->Initialize(texture_manager()); 2664 2665 framebuffer_manager()->AddObserver(this); 2666 2667 return true; 2668 } 2669 2670 Capabilities GLES2DecoderImpl::GetCapabilities() { 2671 DCHECK(initialized()); 2672 2673 Capabilities caps; 2674 2675 caps.fast_npot_mo8_textures = 2676 feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures; 2677 caps.egl_image_external = 2678 feature_info_->feature_flags().oes_egl_image_external; 2679 caps.texture_format_bgra8888 = 2680 feature_info_->feature_flags().ext_texture_format_bgra8888; 2681 caps.texture_format_etc1 = 2682 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture; 2683 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle; 2684 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage; 2685 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage; 2686 caps.discard_framebuffer = 2687 feature_info_->feature_flags().ext_discard_framebuffer; 2688 caps.sync_query = feature_info_->feature_flags().chromium_sync_query; 2689 2690 #if defined(OS_MACOSX) 2691 // This is unconditionally true on mac, no need to test for it at runtime. 2692 caps.iosurface = true; 2693 #endif 2694 2695 caps.post_sub_buffer = supports_post_sub_buffer_; 2696 caps.map_image = !!image_manager(); 2697 2698 return caps; 2699 } 2700 2701 void GLES2DecoderImpl::UpdateCapabilities() { 2702 util_.set_num_compressed_texture_formats( 2703 validators_->compressed_texture_format.GetValues().size()); 2704 util_.set_num_shader_binary_formats( 2705 validators_->shader_binary_format.GetValues().size()); 2706 } 2707 2708 bool GLES2DecoderImpl::InitializeShaderTranslator() { 2709 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator"); 2710 2711 if (!use_shader_translator_) { 2712 return true; 2713 } 2714 ShBuiltInResources resources; 2715 ShInitBuiltInResources(&resources); 2716 resources.MaxVertexAttribs = group_->max_vertex_attribs(); 2717 resources.MaxVertexUniformVectors = 2718 group_->max_vertex_uniform_vectors(); 2719 resources.MaxVaryingVectors = group_->max_varying_vectors(); 2720 resources.MaxVertexTextureImageUnits = 2721 group_->max_vertex_texture_image_units(); 2722 resources.MaxCombinedTextureImageUnits = group_->max_texture_units(); 2723 resources.MaxTextureImageUnits = group_->max_texture_image_units(); 2724 resources.MaxFragmentUniformVectors = 2725 group_->max_fragment_uniform_vectors(); 2726 resources.MaxDrawBuffers = group_->max_draw_buffers(); 2727 resources.MaxExpressionComplexity = 256; 2728 resources.MaxCallStackDepth = 256; 2729 2730 #if (ANGLE_SH_VERSION >= 110) 2731 GLint range[2] = { 0, 0 }; 2732 GLint precision = 0; 2733 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, 2734 range, &precision); 2735 resources.FragmentPrecisionHigh = 2736 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision); 2737 #endif 2738 2739 if (force_webgl_glsl_validation_) { 2740 resources.OES_standard_derivatives = derivatives_explicitly_enabled_; 2741 resources.EXT_frag_depth = frag_depth_explicitly_enabled_; 2742 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_; 2743 if (!draw_buffers_explicitly_enabled_) 2744 resources.MaxDrawBuffers = 1; 2745 #if (ANGLE_SH_VERSION >= 123) 2746 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_; 2747 #endif 2748 } else { 2749 resources.OES_standard_derivatives = 2750 features().oes_standard_derivatives ? 1 : 0; 2751 resources.ARB_texture_rectangle = 2752 features().arb_texture_rectangle ? 1 : 0; 2753 resources.OES_EGL_image_external = 2754 features().oes_egl_image_external ? 1 : 0; 2755 resources.EXT_draw_buffers = 2756 features().ext_draw_buffers ? 1 : 0; 2757 resources.EXT_frag_depth = 2758 features().ext_frag_depth ? 1 : 0; 2759 #if (ANGLE_SH_VERSION >= 123) 2760 resources.EXT_shader_texture_lod = 2761 features().ext_shader_texture_lod ? 1 : 0; 2762 #endif 2763 } 2764 2765 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC 2766 : SH_GLES2_SPEC; 2767 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing) 2768 #if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108 2769 resources.HashFunction = &CityHashForAngle; 2770 #else 2771 resources.HashFunction = &CityHash64; 2772 #endif 2773 else 2774 resources.HashFunction = NULL; 2775 ShaderTranslatorInterface::GlslImplementationType implementation_type = 2776 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ? 2777 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl; 2778 int driver_bug_workarounds = 0; 2779 if (workarounds().needs_glsl_built_in_function_emulation) 2780 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS; 2781 if (workarounds().init_gl_position_in_vertex_shader) 2782 driver_bug_workarounds |= SH_INIT_GL_POSITION; 2783 if (workarounds().unfold_short_circuit_as_ternary_operation) 2784 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT; 2785 if (workarounds().init_varyings_without_static_use) 2786 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE; 2787 if (workarounds().unroll_for_loop_with_sampler_array_index) 2788 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX; 2789 2790 vertex_translator_ = shader_translator_cache()->GetTranslator( 2791 SH_VERTEX_SHADER, 2792 shader_spec, 2793 &resources, 2794 implementation_type, 2795 static_cast<ShCompileOptions>(driver_bug_workarounds)); 2796 if (!vertex_translator_.get()) { 2797 LOG(ERROR) << "Could not initialize vertex shader translator."; 2798 Destroy(true); 2799 return false; 2800 } 2801 2802 fragment_translator_ = shader_translator_cache()->GetTranslator( 2803 SH_FRAGMENT_SHADER, 2804 shader_spec, 2805 &resources, 2806 implementation_type, 2807 static_cast<ShCompileOptions>(driver_bug_workarounds)); 2808 if (!fragment_translator_.get()) { 2809 LOG(ERROR) << "Could not initialize fragment shader translator."; 2810 Destroy(true); 2811 return false; 2812 } 2813 return true; 2814 } 2815 2816 bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) { 2817 for (GLsizei ii = 0; ii < n; ++ii) { 2818 if (GetBuffer(client_ids[ii])) { 2819 return false; 2820 } 2821 } 2822 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2823 glGenBuffersARB(n, service_ids.get()); 2824 for (GLsizei ii = 0; ii < n; ++ii) { 2825 CreateBuffer(client_ids[ii], service_ids[ii]); 2826 } 2827 return true; 2828 } 2829 2830 bool GLES2DecoderImpl::GenFramebuffersHelper( 2831 GLsizei n, const GLuint* client_ids) { 2832 for (GLsizei ii = 0; ii < n; ++ii) { 2833 if (GetFramebuffer(client_ids[ii])) { 2834 return false; 2835 } 2836 } 2837 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2838 glGenFramebuffersEXT(n, service_ids.get()); 2839 for (GLsizei ii = 0; ii < n; ++ii) { 2840 CreateFramebuffer(client_ids[ii], service_ids[ii]); 2841 } 2842 return true; 2843 } 2844 2845 bool GLES2DecoderImpl::GenRenderbuffersHelper( 2846 GLsizei n, const GLuint* client_ids) { 2847 for (GLsizei ii = 0; ii < n; ++ii) { 2848 if (GetRenderbuffer(client_ids[ii])) { 2849 return false; 2850 } 2851 } 2852 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2853 glGenRenderbuffersEXT(n, service_ids.get()); 2854 for (GLsizei ii = 0; ii < n; ++ii) { 2855 CreateRenderbuffer(client_ids[ii], service_ids[ii]); 2856 } 2857 return true; 2858 } 2859 2860 bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) { 2861 for (GLsizei ii = 0; ii < n; ++ii) { 2862 if (GetTexture(client_ids[ii])) { 2863 return false; 2864 } 2865 } 2866 scoped_ptr<GLuint[]> service_ids(new GLuint[n]); 2867 glGenTextures(n, service_ids.get()); 2868 for (GLsizei ii = 0; ii < n; ++ii) { 2869 CreateTexture(client_ids[ii], service_ids[ii]); 2870 } 2871 return true; 2872 } 2873 2874 void GLES2DecoderImpl::DeleteBuffersHelper( 2875 GLsizei n, const GLuint* client_ids) { 2876 for (GLsizei ii = 0; ii < n; ++ii) { 2877 Buffer* buffer = GetBuffer(client_ids[ii]); 2878 if (buffer && !buffer->IsDeleted()) { 2879 state_.vertex_attrib_manager->Unbind(buffer); 2880 if (state_.bound_array_buffer.get() == buffer) { 2881 state_.bound_array_buffer = NULL; 2882 } 2883 RemoveBuffer(client_ids[ii]); 2884 } 2885 } 2886 } 2887 2888 void GLES2DecoderImpl::DeleteFramebuffersHelper( 2889 GLsizei n, const GLuint* client_ids) { 2890 bool supports_separate_framebuffer_binds = 2891 features().chromium_framebuffer_multisample; 2892 2893 for (GLsizei ii = 0; ii < n; ++ii) { 2894 Framebuffer* framebuffer = 2895 GetFramebuffer(client_ids[ii]); 2896 if (framebuffer && !framebuffer->IsDeleted()) { 2897 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { 2898 framebuffer_state_.bound_draw_framebuffer = NULL; 2899 framebuffer_state_.clear_state_dirty = true; 2900 GLenum target = supports_separate_framebuffer_binds ? 2901 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2902 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2903 } 2904 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) { 2905 framebuffer_state_.bound_read_framebuffer = NULL; 2906 GLenum target = supports_separate_framebuffer_binds ? 2907 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2908 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2909 } 2910 OnFboChanged(); 2911 RemoveFramebuffer(client_ids[ii]); 2912 } 2913 } 2914 } 2915 2916 void GLES2DecoderImpl::DeleteRenderbuffersHelper( 2917 GLsizei n, const GLuint* client_ids) { 2918 bool supports_separate_framebuffer_binds = 2919 features().chromium_framebuffer_multisample; 2920 for (GLsizei ii = 0; ii < n; ++ii) { 2921 Renderbuffer* renderbuffer = 2922 GetRenderbuffer(client_ids[ii]); 2923 if (renderbuffer && !renderbuffer->IsDeleted()) { 2924 if (state_.bound_renderbuffer.get() == renderbuffer) { 2925 state_.bound_renderbuffer = NULL; 2926 } 2927 // Unbind from current framebuffers. 2928 if (supports_separate_framebuffer_binds) { 2929 if (framebuffer_state_.bound_read_framebuffer.get()) { 2930 framebuffer_state_.bound_read_framebuffer 2931 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer); 2932 } 2933 if (framebuffer_state_.bound_draw_framebuffer.get()) { 2934 framebuffer_state_.bound_draw_framebuffer 2935 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); 2936 } 2937 } else { 2938 if (framebuffer_state_.bound_draw_framebuffer.get()) { 2939 framebuffer_state_.bound_draw_framebuffer 2940 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer); 2941 } 2942 } 2943 framebuffer_state_.clear_state_dirty = true; 2944 RemoveRenderbuffer(client_ids[ii]); 2945 } 2946 } 2947 } 2948 2949 void GLES2DecoderImpl::DeleteTexturesHelper( 2950 GLsizei n, const GLuint* client_ids) { 2951 bool supports_separate_framebuffer_binds = 2952 features().chromium_framebuffer_multisample; 2953 for (GLsizei ii = 0; ii < n; ++ii) { 2954 TextureRef* texture_ref = GetTexture(client_ids[ii]); 2955 if (texture_ref) { 2956 Texture* texture = texture_ref->texture(); 2957 if (texture->IsAttachedToFramebuffer()) { 2958 framebuffer_state_.clear_state_dirty = true; 2959 } 2960 // Unbind texture_ref from texture_ref units. 2961 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) { 2962 state_.texture_units[jj].Unbind(texture_ref); 2963 } 2964 // Unbind from current framebuffers. 2965 if (supports_separate_framebuffer_binds) { 2966 if (framebuffer_state_.bound_read_framebuffer.get()) { 2967 framebuffer_state_.bound_read_framebuffer 2968 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref); 2969 } 2970 if (framebuffer_state_.bound_draw_framebuffer.get()) { 2971 framebuffer_state_.bound_draw_framebuffer 2972 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref); 2973 } 2974 } else { 2975 if (framebuffer_state_.bound_draw_framebuffer.get()) { 2976 framebuffer_state_.bound_draw_framebuffer 2977 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref); 2978 } 2979 } 2980 #if defined(OS_MACOSX) 2981 GLuint service_id = texture->service_id(); 2982 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) { 2983 ReleaseIOSurfaceForTexture(service_id); 2984 } 2985 #endif 2986 RemoveTexture(client_ids[ii]); 2987 } 2988 } 2989 } 2990 2991 // } // anonymous namespace 2992 2993 bool GLES2DecoderImpl::MakeCurrent() { 2994 if (!context_.get()) 2995 return false; 2996 2997 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) { 2998 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; 2999 3000 // Some D3D drivers cannot recover from device lost in the GPU process 3001 // sandbox. Allow a new GPU process to launch. 3002 if (workarounds().exit_on_context_lost) { 3003 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset" 3004 << " a D3D device in the Chrome GPU process sandbox."; 3005 #if defined(OS_WIN) 3006 base::win::SetShouldCrashOnProcessDetach(false); 3007 #endif 3008 exit(0); 3009 } 3010 3011 return false; 3012 } 3013 3014 ProcessFinishedAsyncTransfers(); 3015 3016 // Rebind the FBO if it was unbound by the context. 3017 if (workarounds().unbind_fbo_on_context_switch) 3018 RestoreFramebufferBindings(); 3019 3020 framebuffer_state_.clear_state_dirty = true; 3021 3022 return true; 3023 } 3024 3025 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() { 3026 ProcessPendingReadPixels(); 3027 if (engine() && query_manager_.get()) 3028 query_manager_->ProcessPendingTransferQueries(); 3029 3030 // TODO(epenner): Is there a better place to do this? 3031 // This needs to occur before we execute any batch of commands 3032 // from the client, as the client may have recieved an async 3033 // completion while issuing those commands. 3034 // "DidFlushStart" would be ideal if we had such a callback. 3035 async_pixel_transfer_manager_->BindCompletedAsyncTransfers(); 3036 } 3037 3038 static void RebindCurrentFramebuffer( 3039 GLenum target, 3040 Framebuffer* framebuffer, 3041 GLuint back_buffer_service_id) { 3042 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0; 3043 3044 if (framebuffer_id == 0) { 3045 framebuffer_id = back_buffer_service_id; 3046 } 3047 3048 glBindFramebufferEXT(target, framebuffer_id); 3049 } 3050 3051 void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { 3052 framebuffer_state_.clear_state_dirty = true; 3053 3054 if (!features().chromium_framebuffer_multisample) { 3055 RebindCurrentFramebuffer( 3056 GL_FRAMEBUFFER, 3057 framebuffer_state_.bound_draw_framebuffer.get(), 3058 GetBackbufferServiceId()); 3059 } else { 3060 RebindCurrentFramebuffer( 3061 GL_READ_FRAMEBUFFER_EXT, 3062 framebuffer_state_.bound_read_framebuffer.get(), 3063 GetBackbufferServiceId()); 3064 RebindCurrentFramebuffer( 3065 GL_DRAW_FRAMEBUFFER_EXT, 3066 framebuffer_state_.bound_draw_framebuffer.get(), 3067 GetBackbufferServiceId()); 3068 } 3069 OnFboChanged(); 3070 } 3071 3072 bool GLES2DecoderImpl::CheckFramebufferValid( 3073 Framebuffer* framebuffer, 3074 GLenum target, const char* func_name) { 3075 if (!framebuffer) { 3076 if (backbuffer_needs_clear_bits_) { 3077 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 3078 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 3079 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3080 glClearStencil(0); 3081 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1); 3082 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1); 3083 glClearDepth(1.0f); 3084 state_.SetDeviceDepthMask(GL_TRUE); 3085 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 3086 bool reset_draw_buffer = false; 3087 if ((backbuffer_needs_clear_bits_ | GL_COLOR_BUFFER_BIT) != 0 && 3088 group_->draw_buffer() == GL_NONE) { 3089 reset_draw_buffer = true; 3090 GLenum buf = GL_BACK; 3091 if (GetBackbufferServiceId() != 0) // emulated backbuffer 3092 buf = GL_COLOR_ATTACHMENT0; 3093 glDrawBuffersARB(1, &buf); 3094 } 3095 glClear(backbuffer_needs_clear_bits_); 3096 if (reset_draw_buffer) { 3097 GLenum buf = GL_NONE; 3098 glDrawBuffersARB(1, &buf); 3099 } 3100 backbuffer_needs_clear_bits_ = 0; 3101 RestoreClearState(); 3102 } 3103 return true; 3104 } 3105 3106 if (framebuffer_manager()->IsComplete(framebuffer)) { 3107 return true; 3108 } 3109 3110 GLenum completeness = framebuffer->IsPossiblyComplete(); 3111 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 3112 LOCAL_SET_GL_ERROR( 3113 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete"); 3114 return false; 3115 } 3116 3117 // Are all the attachments cleared? 3118 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() || 3119 texture_manager()->HaveUnclearedMips()) { 3120 if (!framebuffer->IsCleared()) { 3121 // Can we clear them? 3122 if (framebuffer->GetStatus(texture_manager(), target) != 3123 GL_FRAMEBUFFER_COMPLETE) { 3124 LOCAL_SET_GL_ERROR( 3125 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 3126 "framebuffer incomplete (clear)"); 3127 return false; 3128 } 3129 ClearUnclearedAttachments(target, framebuffer); 3130 } 3131 } 3132 3133 if (!framebuffer_manager()->IsComplete(framebuffer)) { 3134 if (framebuffer->GetStatus(texture_manager(), target) != 3135 GL_FRAMEBUFFER_COMPLETE) { 3136 LOCAL_SET_GL_ERROR( 3137 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 3138 "framebuffer incomplete (check)"); 3139 return false; 3140 } 3141 framebuffer_manager()->MarkAsComplete(framebuffer); 3142 } 3143 3144 // NOTE: At this point we don't know if the framebuffer is complete but 3145 // we DO know that everything that needs to be cleared has been cleared. 3146 return true; 3147 } 3148 3149 bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) { 3150 if (!features().chromium_framebuffer_multisample) { 3151 bool valid = CheckFramebufferValid( 3152 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT, 3153 func_name); 3154 3155 if (valid) 3156 OnUseFramebuffer(); 3157 3158 return valid; 3159 } 3160 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(), 3161 GL_DRAW_FRAMEBUFFER_EXT, 3162 func_name) && 3163 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(), 3164 GL_READ_FRAMEBUFFER_EXT, 3165 func_name); 3166 } 3167 3168 gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { 3169 Framebuffer* framebuffer = 3170 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3171 if (framebuffer != NULL) { 3172 const Framebuffer::Attachment* attachment = 3173 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0); 3174 if (attachment) { 3175 return gfx::Size(attachment->width(), attachment->height()); 3176 } 3177 return gfx::Size(0, 0); 3178 } else if (offscreen_target_frame_buffer_.get()) { 3179 return offscreen_size_; 3180 } else { 3181 return surface_->GetSize(); 3182 } 3183 } 3184 3185 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() { 3186 Framebuffer* framebuffer = 3187 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3188 if (framebuffer != NULL) { 3189 return framebuffer->GetColorAttachmentTextureType(); 3190 } else { 3191 return GL_UNSIGNED_BYTE; 3192 } 3193 } 3194 3195 GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { 3196 Framebuffer* framebuffer = 3197 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3198 if (framebuffer != NULL) { 3199 return framebuffer->GetColorAttachmentFormat(); 3200 } else if (offscreen_target_frame_buffer_.get()) { 3201 return offscreen_target_color_format_; 3202 } else { 3203 return back_buffer_color_format_; 3204 } 3205 } 3206 3207 GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() { 3208 Framebuffer* framebuffer = 3209 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3210 if (framebuffer != NULL) { 3211 return framebuffer->GetColorAttachmentFormat(); 3212 } else if (offscreen_target_frame_buffer_.get()) { 3213 return offscreen_target_color_format_; 3214 } else { 3215 return back_buffer_color_format_; 3216 } 3217 } 3218 3219 void GLES2DecoderImpl::UpdateParentTextureInfo() { 3220 if (!offscreen_saved_color_texture_info_.get()) 3221 return; 3222 GLenum target = offscreen_saved_color_texture_info_->texture()->target(); 3223 glBindTexture(target, offscreen_saved_color_texture_info_->service_id()); 3224 texture_manager()->SetLevelInfo( 3225 offscreen_saved_color_texture_info_.get(), 3226 GL_TEXTURE_2D, 3227 0, // level 3228 GL_RGBA, 3229 offscreen_size_.width(), 3230 offscreen_size_.height(), 3231 1, // depth 3232 0, // border 3233 GL_RGBA, 3234 GL_UNSIGNED_BYTE, 3235 true); 3236 texture_manager()->SetParameteri( 3237 "UpdateParentTextureInfo", 3238 GetErrorState(), 3239 offscreen_saved_color_texture_info_.get(), 3240 GL_TEXTURE_MAG_FILTER, 3241 GL_NEAREST); 3242 texture_manager()->SetParameteri( 3243 "UpdateParentTextureInfo", 3244 GetErrorState(), 3245 offscreen_saved_color_texture_info_.get(), 3246 GL_TEXTURE_MIN_FILTER, 3247 GL_NEAREST); 3248 texture_manager()->SetParameteri( 3249 "UpdateParentTextureInfo", 3250 GetErrorState(), 3251 offscreen_saved_color_texture_info_.get(), 3252 GL_TEXTURE_WRAP_S, 3253 GL_CLAMP_TO_EDGE); 3254 texture_manager()->SetParameteri( 3255 "UpdateParentTextureInfo", 3256 GetErrorState(), 3257 offscreen_saved_color_texture_info_.get(), 3258 GL_TEXTURE_WRAP_T, 3259 GL_CLAMP_TO_EDGE); 3260 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 3261 &state_, target); 3262 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0); 3263 } 3264 3265 void GLES2DecoderImpl::SetResizeCallback( 3266 const base::Callback<void(gfx::Size, float)>& callback) { 3267 resize_callback_ = callback; 3268 } 3269 3270 Logger* GLES2DecoderImpl::GetLogger() { 3271 return &logger_; 3272 } 3273 3274 void GLES2DecoderImpl::BeginDecoding() { 3275 gpu_tracer_->BeginDecoding(); 3276 gpu_trace_commands_ = gpu_tracer_->IsTracing(); 3277 } 3278 3279 void GLES2DecoderImpl::EndDecoding() { 3280 gpu_tracer_->EndDecoding(); 3281 } 3282 3283 ErrorState* GLES2DecoderImpl::GetErrorState() { 3284 return state_.GetErrorState(); 3285 } 3286 3287 void GLES2DecoderImpl::SetShaderCacheCallback( 3288 const ShaderCacheCallback& callback) { 3289 shader_cache_callback_ = callback; 3290 } 3291 3292 void GLES2DecoderImpl::SetWaitSyncPointCallback( 3293 const WaitSyncPointCallback& callback) { 3294 wait_sync_point_callback_ = callback; 3295 } 3296 3297 AsyncPixelTransferManager* 3298 GLES2DecoderImpl::GetAsyncPixelTransferManager() { 3299 return async_pixel_transfer_manager_.get(); 3300 } 3301 3302 void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() { 3303 async_pixel_transfer_manager_.reset(); 3304 } 3305 3306 void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest( 3307 AsyncPixelTransferManager* manager) { 3308 async_pixel_transfer_manager_ = make_scoped_ptr(manager); 3309 } 3310 3311 bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, 3312 uint32* service_texture_id) { 3313 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id); 3314 if (texture_ref) { 3315 *service_texture_id = texture_ref->service_id(); 3316 return true; 3317 } 3318 return false; 3319 } 3320 3321 uint32 GLES2DecoderImpl::GetTextureUploadCount() { 3322 return texture_state_.texture_upload_count + 3323 async_pixel_transfer_manager_->GetTextureUploadCount(); 3324 } 3325 3326 base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() { 3327 return texture_state_.total_texture_upload_time + 3328 async_pixel_transfer_manager_->GetTotalTextureUploadTime(); 3329 } 3330 3331 base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() { 3332 return total_processing_commands_time_; 3333 } 3334 3335 void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) { 3336 total_processing_commands_time_ += time; 3337 } 3338 3339 void GLES2DecoderImpl::Destroy(bool have_context) { 3340 if (!initialized()) 3341 return; 3342 3343 DCHECK(!have_context || context_->IsCurrent(NULL)); 3344 3345 // Unbind everything. 3346 state_.vertex_attrib_manager = NULL; 3347 state_.default_vertex_attrib_manager = NULL; 3348 state_.texture_units.clear(); 3349 state_.bound_array_buffer = NULL; 3350 state_.current_queries.clear(); 3351 framebuffer_state_.bound_read_framebuffer = NULL; 3352 framebuffer_state_.bound_draw_framebuffer = NULL; 3353 state_.bound_renderbuffer = NULL; 3354 3355 if (offscreen_saved_color_texture_info_.get()) { 3356 DCHECK(offscreen_target_color_texture_); 3357 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(), 3358 offscreen_saved_color_texture_->id()); 3359 offscreen_saved_color_texture_->Invalidate(); 3360 offscreen_saved_color_texture_info_ = NULL; 3361 } 3362 if (have_context) { 3363 if (copy_texture_CHROMIUM_.get()) { 3364 copy_texture_CHROMIUM_->Destroy(); 3365 copy_texture_CHROMIUM_.reset(); 3366 } 3367 3368 if (state_.current_program.get()) { 3369 program_manager()->UnuseProgram(shader_manager(), 3370 state_.current_program.get()); 3371 } 3372 3373 if (attrib_0_buffer_id_) { 3374 glDeleteBuffersARB(1, &attrib_0_buffer_id_); 3375 } 3376 if (fixed_attrib_buffer_id_) { 3377 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_); 3378 } 3379 3380 if (validation_texture_) { 3381 glDeleteTextures(1, &validation_texture_); 3382 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_); 3383 glDeleteFramebuffersEXT(1, &validation_fbo_); 3384 } 3385 3386 if (offscreen_target_frame_buffer_.get()) 3387 offscreen_target_frame_buffer_->Destroy(); 3388 if (offscreen_target_color_texture_.get()) 3389 offscreen_target_color_texture_->Destroy(); 3390 if (offscreen_target_color_render_buffer_.get()) 3391 offscreen_target_color_render_buffer_->Destroy(); 3392 if (offscreen_target_depth_render_buffer_.get()) 3393 offscreen_target_depth_render_buffer_->Destroy(); 3394 if (offscreen_target_stencil_render_buffer_.get()) 3395 offscreen_target_stencil_render_buffer_->Destroy(); 3396 if (offscreen_saved_frame_buffer_.get()) 3397 offscreen_saved_frame_buffer_->Destroy(); 3398 if (offscreen_saved_color_texture_.get()) 3399 offscreen_saved_color_texture_->Destroy(); 3400 if (offscreen_resolved_frame_buffer_.get()) 3401 offscreen_resolved_frame_buffer_->Destroy(); 3402 if (offscreen_resolved_color_texture_.get()) 3403 offscreen_resolved_color_texture_->Destroy(); 3404 } else { 3405 if (offscreen_target_frame_buffer_.get()) 3406 offscreen_target_frame_buffer_->Invalidate(); 3407 if (offscreen_target_color_texture_.get()) 3408 offscreen_target_color_texture_->Invalidate(); 3409 if (offscreen_target_color_render_buffer_.get()) 3410 offscreen_target_color_render_buffer_->Invalidate(); 3411 if (offscreen_target_depth_render_buffer_.get()) 3412 offscreen_target_depth_render_buffer_->Invalidate(); 3413 if (offscreen_target_stencil_render_buffer_.get()) 3414 offscreen_target_stencil_render_buffer_->Invalidate(); 3415 if (offscreen_saved_frame_buffer_.get()) 3416 offscreen_saved_frame_buffer_->Invalidate(); 3417 if (offscreen_saved_color_texture_.get()) 3418 offscreen_saved_color_texture_->Invalidate(); 3419 if (offscreen_resolved_frame_buffer_.get()) 3420 offscreen_resolved_frame_buffer_->Invalidate(); 3421 if (offscreen_resolved_color_texture_.get()) 3422 offscreen_resolved_color_texture_->Invalidate(); 3423 } 3424 3425 // Current program must be cleared after calling ProgramManager::UnuseProgram. 3426 // Otherwise, we can leak objects. http://crbug.com/258772. 3427 // state_.current_program must be reset before group_ is reset because 3428 // the later deletes the ProgramManager object that referred by 3429 // state_.current_program object. 3430 state_.current_program = NULL; 3431 3432 copy_texture_CHROMIUM_.reset(); 3433 3434 if (query_manager_.get()) { 3435 query_manager_->Destroy(have_context); 3436 query_manager_.reset(); 3437 } 3438 3439 if (vertex_array_manager_ .get()) { 3440 vertex_array_manager_->Destroy(have_context); 3441 vertex_array_manager_.reset(); 3442 } 3443 3444 offscreen_target_frame_buffer_.reset(); 3445 offscreen_target_color_texture_.reset(); 3446 offscreen_target_color_render_buffer_.reset(); 3447 offscreen_target_depth_render_buffer_.reset(); 3448 offscreen_target_stencil_render_buffer_.reset(); 3449 offscreen_saved_frame_buffer_.reset(); 3450 offscreen_saved_color_texture_.reset(); 3451 offscreen_resolved_frame_buffer_.reset(); 3452 offscreen_resolved_color_texture_.reset(); 3453 3454 // Need to release these before releasing |group_| which may own the 3455 // ShaderTranslatorCache. 3456 fragment_translator_ = NULL; 3457 vertex_translator_ = NULL; 3458 3459 // Should destroy the transfer manager before the texture manager held 3460 // by the context group. 3461 async_pixel_transfer_manager_.reset(); 3462 3463 if (group_.get()) { 3464 framebuffer_manager()->RemoveObserver(this); 3465 group_->Destroy(this, have_context); 3466 group_ = NULL; 3467 } 3468 3469 if (context_.get()) { 3470 context_->ReleaseCurrent(NULL); 3471 context_ = NULL; 3472 } 3473 3474 #if defined(OS_MACOSX) 3475 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin(); 3476 it != texture_to_io_surface_map_.end(); ++it) { 3477 CFRelease(it->second); 3478 } 3479 texture_to_io_surface_map_.clear(); 3480 #endif 3481 } 3482 3483 void GLES2DecoderImpl::SetSurface( 3484 const scoped_refptr<gfx::GLSurface>& surface) { 3485 DCHECK(context_->IsCurrent(NULL)); 3486 DCHECK(surface_.get()); 3487 surface_ = surface; 3488 RestoreCurrentFramebufferBindings(); 3489 } 3490 3491 void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) { 3492 if (!offscreen_saved_color_texture_.get()) { 3493 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context"; 3494 return; 3495 } 3496 if (!offscreen_saved_color_texture_info_.get()) { 3497 GLuint service_id = offscreen_saved_color_texture_->id(); 3498 offscreen_saved_color_texture_info_ = TextureRef::Create( 3499 texture_manager(), 0, service_id); 3500 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(), 3501 GL_TEXTURE_2D); 3502 UpdateParentTextureInfo(); 3503 } 3504 mailbox_manager()->ProduceTexture( 3505 GL_TEXTURE_2D, mailbox, offscreen_saved_color_texture_info_->texture()); 3506 } 3507 3508 bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { 3509 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3510 if (!is_offscreen) { 3511 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called " 3512 << " with an onscreen framebuffer."; 3513 return false; 3514 } 3515 3516 if (offscreen_size_ == size) 3517 return true; 3518 3519 offscreen_size_ = size; 3520 int w = offscreen_size_.width(); 3521 int h = offscreen_size_.height(); 3522 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) { 3523 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3524 << "to allocate storage due to excessive dimensions."; 3525 return false; 3526 } 3527 3528 // Reallocate the offscreen target buffers. 3529 DCHECK(offscreen_target_color_format_); 3530 if (IsOffscreenBufferMultisampled()) { 3531 if (!offscreen_target_color_render_buffer_->AllocateStorage( 3532 feature_info_, offscreen_size_, offscreen_target_color_format_, 3533 offscreen_target_samples_)) { 3534 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3535 << "to allocate storage for offscreen target color buffer."; 3536 return false; 3537 } 3538 } else { 3539 if (!offscreen_target_color_texture_->AllocateStorage( 3540 offscreen_size_, offscreen_target_color_format_, false)) { 3541 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3542 << "to allocate storage for offscreen target color texture."; 3543 return false; 3544 } 3545 } 3546 if (offscreen_target_depth_format_ && 3547 !offscreen_target_depth_render_buffer_->AllocateStorage( 3548 feature_info_, offscreen_size_, offscreen_target_depth_format_, 3549 offscreen_target_samples_)) { 3550 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3551 << "to allocate storage for offscreen target depth buffer."; 3552 return false; 3553 } 3554 if (offscreen_target_stencil_format_ && 3555 !offscreen_target_stencil_render_buffer_->AllocateStorage( 3556 feature_info_, offscreen_size_, offscreen_target_stencil_format_, 3557 offscreen_target_samples_)) { 3558 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3559 << "to allocate storage for offscreen target stencil buffer."; 3560 return false; 3561 } 3562 3563 // Attach the offscreen target buffers to the target frame buffer. 3564 if (IsOffscreenBufferMultisampled()) { 3565 offscreen_target_frame_buffer_->AttachRenderBuffer( 3566 GL_COLOR_ATTACHMENT0, 3567 offscreen_target_color_render_buffer_.get()); 3568 } else { 3569 offscreen_target_frame_buffer_->AttachRenderTexture( 3570 offscreen_target_color_texture_.get()); 3571 } 3572 if (offscreen_target_depth_format_) { 3573 offscreen_target_frame_buffer_->AttachRenderBuffer( 3574 GL_DEPTH_ATTACHMENT, 3575 offscreen_target_depth_render_buffer_.get()); 3576 } 3577 const bool packed_depth_stencil = 3578 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3579 if (packed_depth_stencil) { 3580 offscreen_target_frame_buffer_->AttachRenderBuffer( 3581 GL_STENCIL_ATTACHMENT, 3582 offscreen_target_depth_render_buffer_.get()); 3583 } else if (offscreen_target_stencil_format_) { 3584 offscreen_target_frame_buffer_->AttachRenderBuffer( 3585 GL_STENCIL_ATTACHMENT, 3586 offscreen_target_stencil_render_buffer_.get()); 3587 } 3588 3589 if (offscreen_target_frame_buffer_->CheckStatus() != 3590 GL_FRAMEBUFFER_COMPLETE) { 3591 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3592 << "because offscreen FBO was incomplete."; 3593 return false; 3594 } 3595 3596 // Clear the target frame buffer. 3597 { 3598 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id()); 3599 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 3600 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 3601 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3602 glClearStencil(0); 3603 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1); 3604 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1); 3605 glClearDepth(0); 3606 state_.SetDeviceDepthMask(GL_TRUE); 3607 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 3608 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 3609 RestoreClearState(); 3610 } 3611 3612 // Destroy the offscreen resolved framebuffers. 3613 if (offscreen_resolved_frame_buffer_.get()) 3614 offscreen_resolved_frame_buffer_->Destroy(); 3615 if (offscreen_resolved_color_texture_.get()) 3616 offscreen_resolved_color_texture_->Destroy(); 3617 offscreen_resolved_color_texture_.reset(); 3618 offscreen_resolved_frame_buffer_.reset(); 3619 3620 return true; 3621 } 3622 3623 error::Error GLES2DecoderImpl::HandleResizeCHROMIUM( 3624 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) { 3625 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws()) 3626 return error::kDeferCommandUntilLater; 3627 3628 GLuint width = static_cast<GLuint>(c.width); 3629 GLuint height = static_cast<GLuint>(c.height); 3630 GLfloat scale_factor = c.scale_factor; 3631 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height); 3632 3633 width = std::max(1U, width); 3634 height = std::max(1U, height); 3635 3636 #if defined(OS_POSIX) && !defined(OS_MACOSX) && \ 3637 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 3638 // Make sure that we are done drawing to the back buffer before resizing. 3639 glFinish(); 3640 #endif 3641 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3642 if (is_offscreen) { 3643 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) { 3644 LOG(ERROR) << "GLES2DecoderImpl: Context lost because " 3645 << "ResizeOffscreenFrameBuffer failed."; 3646 return error::kLostContext; 3647 } 3648 } 3649 3650 if (!resize_callback_.is_null()) { 3651 resize_callback_.Run(gfx::Size(width, height), scale_factor); 3652 DCHECK(context_->IsCurrent(surface_.get())); 3653 if (!context_->IsCurrent(surface_.get())) { 3654 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer " 3655 << "current after resize callback."; 3656 return error::kLostContext; 3657 } 3658 } 3659 3660 return error::kNoError; 3661 } 3662 3663 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { 3664 if (command_id > kStartPoint && command_id < kNumCommands) { 3665 return gles2::GetCommandName(static_cast<CommandId>(command_id)); 3666 } 3667 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); 3668 } 3669 3670 // Decode command with its arguments, and call the corresponding GL function. 3671 // Note: args is a pointer to the command buffer. As such, it could be changed 3672 // by a (malicious) client at any time, so if validation has to happen, it 3673 // should operate on a copy of them. 3674 error::Error GLES2DecoderImpl::DoCommand( 3675 unsigned int command, 3676 unsigned int arg_count, 3677 const void* cmd_data) { 3678 error::Error result = error::kNoError; 3679 if (log_commands()) { 3680 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried 3681 // VLOG(1), no luck. 3682 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: " 3683 << GetCommandName(command); 3684 } 3685 unsigned int command_index = command - kStartPoint - 1; 3686 if (command_index < arraysize(g_command_info)) { 3687 const CommandInfo& info = g_command_info[command_index]; 3688 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); 3689 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || 3690 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { 3691 bool doing_gpu_trace = false; 3692 if (gpu_trace_commands_) { 3693 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) { 3694 doing_gpu_trace = true; 3695 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder); 3696 } 3697 } 3698 3699 uint32 immediate_data_size = 3700 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT 3701 switch (command) { 3702 #define GLES2_CMD_OP(name) \ 3703 case cmds::name::kCmdId: \ 3704 result = Handle ## name( \ 3705 immediate_data_size, \ 3706 *static_cast<const gles2::cmds::name*>(cmd_data)); \ 3707 break; \ 3708 3709 GLES2_COMMAND_LIST(GLES2_CMD_OP) 3710 #undef GLES2_CMD_OP 3711 } 3712 3713 if (doing_gpu_trace) 3714 gpu_tracer_->End(kTraceDecoder); 3715 3716 if (debug()) { 3717 GLenum error; 3718 while ((error = glGetError()) != GL_NO_ERROR) { 3719 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] " 3720 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : " 3721 << GetCommandName(command); 3722 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver"); 3723 } 3724 } 3725 } else { 3726 result = error::kInvalidArguments; 3727 } 3728 } else { 3729 result = DoCommonCommand(command, arg_count, cmd_data); 3730 } 3731 if (result == error::kNoError && current_decoder_error_ != error::kNoError) { 3732 result = current_decoder_error_; 3733 current_decoder_error_ = error::kNoError; 3734 } 3735 return result; 3736 } 3737 3738 void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) { 3739 buffer_manager()->RemoveBuffer(client_id); 3740 } 3741 3742 bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { 3743 if (GetProgram(client_id)) { 3744 return false; 3745 } 3746 GLuint service_id = glCreateProgram(); 3747 if (service_id != 0) { 3748 CreateProgram(client_id, service_id); 3749 } 3750 return true; 3751 } 3752 3753 bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { 3754 if (GetShader(client_id)) { 3755 return false; 3756 } 3757 GLuint service_id = glCreateShader(type); 3758 if (service_id != 0) { 3759 CreateShader(client_id, service_id, type); 3760 } 3761 return true; 3762 } 3763 3764 void GLES2DecoderImpl::DoFinish() { 3765 glFinish(); 3766 ProcessPendingReadPixels(); 3767 ProcessPendingQueries(); 3768 } 3769 3770 void GLES2DecoderImpl::DoFlush() { 3771 glFlush(); 3772 ProcessPendingQueries(); 3773 } 3774 3775 void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { 3776 GLuint texture_index = texture_unit - GL_TEXTURE0; 3777 if (texture_index >= state_.texture_units.size()) { 3778 LOCAL_SET_GL_ERROR_INVALID_ENUM( 3779 "glActiveTexture", texture_unit, "texture_unit"); 3780 return; 3781 } 3782 state_.active_texture_unit = texture_index; 3783 glActiveTexture(texture_unit); 3784 } 3785 3786 void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { 3787 Buffer* buffer = NULL; 3788 GLuint service_id = 0; 3789 if (client_id != 0) { 3790 buffer = GetBuffer(client_id); 3791 if (!buffer) { 3792 if (!group_->bind_generates_resource()) { 3793 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 3794 "glBindBuffer", 3795 "id not generated by glGenBuffers"); 3796 return; 3797 } 3798 3799 // It's a new id so make a buffer buffer for it. 3800 glGenBuffersARB(1, &service_id); 3801 CreateBuffer(client_id, service_id); 3802 buffer = GetBuffer(client_id); 3803 IdAllocatorInterface* id_allocator = 3804 group_->GetIdAllocator(id_namespaces::kBuffers); 3805 id_allocator->MarkAsUsed(client_id); 3806 } 3807 } 3808 LogClientServiceForInfo(buffer, client_id, "glBindBuffer"); 3809 if (buffer) { 3810 if (!buffer_manager()->SetTarget(buffer, target)) { 3811 LOCAL_SET_GL_ERROR( 3812 GL_INVALID_OPERATION, 3813 "glBindBuffer", "buffer bound to more than 1 target"); 3814 return; 3815 } 3816 service_id = buffer->service_id(); 3817 } 3818 switch (target) { 3819 case GL_ARRAY_BUFFER: 3820 state_.bound_array_buffer = buffer; 3821 break; 3822 case GL_ELEMENT_ARRAY_BUFFER: 3823 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer); 3824 break; 3825 default: 3826 NOTREACHED(); // Validation should prevent us getting here. 3827 break; 3828 } 3829 glBindBuffer(target, service_id); 3830 } 3831 3832 bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha( 3833 bool all_draw_buffers) { 3834 Framebuffer* framebuffer = 3835 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3836 if (!all_draw_buffers || !framebuffer) { 3837 return (GLES2Util::GetChannelsForFormat( 3838 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0; 3839 } 3840 return framebuffer->HasAlphaMRT(); 3841 } 3842 3843 bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() { 3844 Framebuffer* framebuffer = 3845 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3846 if (framebuffer) { 3847 return framebuffer->HasDepthAttachment(); 3848 } 3849 if (offscreen_target_frame_buffer_.get()) { 3850 return offscreen_target_depth_format_ != 0; 3851 } 3852 return back_buffer_has_depth_; 3853 } 3854 3855 bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() { 3856 Framebuffer* framebuffer = 3857 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3858 if (framebuffer) { 3859 return framebuffer->HasStencilAttachment(); 3860 } 3861 if (offscreen_target_frame_buffer_.get()) { 3862 return offscreen_target_stencil_format_ != 0 || 3863 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3864 } 3865 return back_buffer_has_stencil_; 3866 } 3867 3868 void GLES2DecoderImpl::ApplyDirtyState() { 3869 if (framebuffer_state_.clear_state_dirty) { 3870 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true); 3871 state_.SetDeviceColorMask(state_.color_mask_red, 3872 state_.color_mask_green, 3873 state_.color_mask_blue, 3874 state_.color_mask_alpha && have_alpha); 3875 3876 bool have_depth = BoundFramebufferHasDepthAttachment(); 3877 state_.SetDeviceDepthMask(state_.depth_mask && have_depth); 3878 3879 bool have_stencil = BoundFramebufferHasStencilAttachment(); 3880 state_.SetDeviceStencilMaskSeparate( 3881 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0); 3882 state_.SetDeviceStencilMaskSeparate( 3883 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0); 3884 3885 state_.SetDeviceCapabilityState( 3886 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth); 3887 state_.SetDeviceCapabilityState( 3888 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil); 3889 framebuffer_state_.clear_state_dirty = false; 3890 } 3891 } 3892 3893 GLuint GLES2DecoderImpl::GetBackbufferServiceId() const { 3894 return (offscreen_target_frame_buffer_.get()) 3895 ? offscreen_target_frame_buffer_->id() 3896 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0); 3897 } 3898 3899 void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) const { 3900 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState", 3901 "context", logger_.GetLogPrefix()); 3902 // Restore the Framebuffer first because of bugs in Intel drivers. 3903 // Intel drivers incorrectly clip the viewport settings to 3904 // the size of the current framebuffer object. 3905 RestoreFramebufferBindings(); 3906 state_.RestoreState(prev_state); 3907 } 3908 3909 void GLES2DecoderImpl::RestoreFramebufferBindings() const { 3910 GLuint service_id = 3911 framebuffer_state_.bound_draw_framebuffer.get() 3912 ? framebuffer_state_.bound_draw_framebuffer->service_id() 3913 : GetBackbufferServiceId(); 3914 if (!features().chromium_framebuffer_multisample) { 3915 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id); 3916 } else { 3917 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id); 3918 service_id = framebuffer_state_.bound_read_framebuffer.get() 3919 ? framebuffer_state_.bound_read_framebuffer->service_id() 3920 : GetBackbufferServiceId(); 3921 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id); 3922 } 3923 OnFboChanged(); 3924 } 3925 3926 void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const { 3927 Texture* texture = texture_manager()->GetTextureForServiceId(service_id); 3928 if (texture) { 3929 GLenum target = texture->target(); 3930 glBindTexture(target, service_id); 3931 glTexParameteri( 3932 target, GL_TEXTURE_WRAP_S, texture->wrap_s()); 3933 glTexParameteri( 3934 target, GL_TEXTURE_WRAP_T, texture->wrap_t()); 3935 glTexParameteri( 3936 target, GL_TEXTURE_MIN_FILTER, texture->min_filter()); 3937 glTexParameteri( 3938 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter()); 3939 RestoreTextureUnitBindings(state_.active_texture_unit); 3940 } 3941 } 3942 3943 void GLES2DecoderImpl::ClearAllAttributes() const { 3944 // Must use native VAO 0, as RestoreAllAttributes can't fully restore 3945 // other VAOs. 3946 if (feature_info_->feature_flags().native_vertex_array_object) 3947 glBindVertexArrayOES(0); 3948 3949 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) { 3950 if (i != 0) // Never disable attribute 0 3951 glDisableVertexAttribArray(i); 3952 if(features().angle_instanced_arrays) 3953 glVertexAttribDivisorANGLE(i, 0); 3954 } 3955 } 3956 3957 void GLES2DecoderImpl::RestoreAllAttributes() const { 3958 state_.RestoreVertexAttribs(); 3959 } 3960 3961 void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) { 3962 state_.SetIgnoreCachedStateForTest(ignore); 3963 } 3964 3965 void GLES2DecoderImpl::OnFboChanged() const { 3966 if (workarounds().restore_scissor_on_fbo_change) 3967 state_.fbo_binding_for_scissor_workaround_dirty_ = true; 3968 } 3969 3970 // Called after the FBO is checked for completeness. 3971 void GLES2DecoderImpl::OnUseFramebuffer() const { 3972 if (state_.fbo_binding_for_scissor_workaround_dirty_) { 3973 state_.fbo_binding_for_scissor_workaround_dirty_ = false; 3974 // The driver forgets the correct scissor when modifying the FBO binding. 3975 glScissor(state_.scissor_x, 3976 state_.scissor_y, 3977 state_.scissor_width, 3978 state_.scissor_height); 3979 3980 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker, 3981 // it's unclear how this bug works. 3982 glFlush(); 3983 } 3984 } 3985 3986 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { 3987 Framebuffer* framebuffer = NULL; 3988 GLuint service_id = 0; 3989 if (client_id != 0) { 3990 framebuffer = GetFramebuffer(client_id); 3991 if (!framebuffer) { 3992 if (!group_->bind_generates_resource()) { 3993 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 3994 "glBindFramebuffer", 3995 "id not generated by glGenFramebuffers"); 3996 return; 3997 } 3998 3999 // It's a new id so make a framebuffer framebuffer for it. 4000 glGenFramebuffersEXT(1, &service_id); 4001 CreateFramebuffer(client_id, service_id); 4002 framebuffer = GetFramebuffer(client_id); 4003 IdAllocatorInterface* id_allocator = 4004 group_->GetIdAllocator(id_namespaces::kFramebuffers); 4005 id_allocator->MarkAsUsed(client_id); 4006 } else { 4007 service_id = framebuffer->service_id(); 4008 } 4009 framebuffer->MarkAsValid(); 4010 } 4011 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer"); 4012 4013 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { 4014 framebuffer_state_.bound_draw_framebuffer = framebuffer; 4015 } 4016 4017 // vmiura: This looks like dup code 4018 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { 4019 framebuffer_state_.bound_read_framebuffer = framebuffer; 4020 } 4021 4022 framebuffer_state_.clear_state_dirty = true; 4023 4024 // If we are rendering to the backbuffer get the FBO id for any simulated 4025 // backbuffer. 4026 if (framebuffer == NULL) { 4027 service_id = GetBackbufferServiceId(); 4028 } 4029 4030 glBindFramebufferEXT(target, service_id); 4031 OnFboChanged(); 4032 } 4033 4034 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { 4035 Renderbuffer* renderbuffer = NULL; 4036 GLuint service_id = 0; 4037 if (client_id != 0) { 4038 renderbuffer = GetRenderbuffer(client_id); 4039 if (!renderbuffer) { 4040 if (!group_->bind_generates_resource()) { 4041 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4042 "glBindRenderbuffer", 4043 "id not generated by glGenRenderbuffers"); 4044 return; 4045 } 4046 4047 // It's a new id so make a renderbuffer renderbuffer for it. 4048 glGenRenderbuffersEXT(1, &service_id); 4049 CreateRenderbuffer(client_id, service_id); 4050 renderbuffer = GetRenderbuffer(client_id); 4051 IdAllocatorInterface* id_allocator = 4052 group_->GetIdAllocator(id_namespaces::kRenderbuffers); 4053 id_allocator->MarkAsUsed(client_id); 4054 } else { 4055 service_id = renderbuffer->service_id(); 4056 } 4057 renderbuffer->MarkAsValid(); 4058 } 4059 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer"); 4060 state_.bound_renderbuffer = renderbuffer; 4061 glBindRenderbufferEXT(target, service_id); 4062 } 4063 4064 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { 4065 TextureRef* texture_ref = NULL; 4066 GLuint service_id = 0; 4067 if (client_id != 0) { 4068 texture_ref = GetTexture(client_id); 4069 if (!texture_ref) { 4070 if (!group_->bind_generates_resource()) { 4071 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4072 "glBindTexture", 4073 "id not generated by glGenTextures"); 4074 return; 4075 } 4076 4077 // It's a new id so make a texture texture for it. 4078 glGenTextures(1, &service_id); 4079 DCHECK_NE(0u, service_id); 4080 CreateTexture(client_id, service_id); 4081 texture_ref = GetTexture(client_id); 4082 IdAllocatorInterface* id_allocator = 4083 group_->GetIdAllocator(id_namespaces::kTextures); 4084 id_allocator->MarkAsUsed(client_id); 4085 } 4086 } else { 4087 texture_ref = texture_manager()->GetDefaultTextureInfo(target); 4088 } 4089 4090 // Check the texture exists 4091 if (texture_ref) { 4092 Texture* texture = texture_ref->texture(); 4093 // Check that we are not trying to bind it to a different target. 4094 if (texture->target() != 0 && texture->target() != target) { 4095 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 4096 "glBindTexture", 4097 "texture bound to more than 1 target."); 4098 return; 4099 } 4100 LogClientServiceForInfo(texture, client_id, "glBindTexture"); 4101 if (texture->target() == 0) { 4102 texture_manager()->SetTarget(texture_ref, target); 4103 } 4104 glBindTexture(target, texture->service_id()); 4105 } else { 4106 glBindTexture(target, 0); 4107 } 4108 4109 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4110 unit.bind_target = target; 4111 switch (target) { 4112 case GL_TEXTURE_2D: 4113 unit.bound_texture_2d = texture_ref; 4114 break; 4115 case GL_TEXTURE_CUBE_MAP: 4116 unit.bound_texture_cube_map = texture_ref; 4117 break; 4118 case GL_TEXTURE_EXTERNAL_OES: 4119 unit.bound_texture_external_oes = texture_ref; 4120 break; 4121 case GL_TEXTURE_RECTANGLE_ARB: 4122 unit.bound_texture_rectangle_arb = texture_ref; 4123 break; 4124 default: 4125 NOTREACHED(); // Validation should prevent us getting here. 4126 break; 4127 } 4128 } 4129 4130 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { 4131 if (state_.vertex_attrib_manager->Enable(index, false)) { 4132 if (index != 0 || 4133 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 4134 glDisableVertexAttribArray(index); 4135 } 4136 } else { 4137 LOCAL_SET_GL_ERROR( 4138 GL_INVALID_VALUE, 4139 "glDisableVertexAttribArray", "index out of range"); 4140 } 4141 } 4142 4143 void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target, 4144 GLsizei numAttachments, 4145 const GLenum* attachments) { 4146 Framebuffer* framebuffer = 4147 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4148 4149 // Validates the attachments. If one of them fails 4150 // the whole command fails. 4151 for (GLsizei i = 0; i < numAttachments; ++i) { 4152 if ((framebuffer && 4153 !validators_->attachment.IsValid(attachments[i])) || 4154 (!framebuffer && 4155 !validators_->backbuffer_attachment.IsValid(attachments[i]))) { 4156 LOCAL_SET_GL_ERROR_INVALID_ENUM( 4157 "glDiscardFramebufferEXT", attachments[i], "attachments"); 4158 return; 4159 } 4160 } 4161 4162 // Marks each one of them as not cleared 4163 for (GLsizei i = 0; i < numAttachments; ++i) { 4164 if (framebuffer) { 4165 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(), 4166 texture_manager(), 4167 attachments[i], 4168 false); 4169 } else { 4170 switch (attachments[i]) { 4171 case GL_COLOR_EXT: 4172 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT; 4173 break; 4174 case GL_DEPTH_EXT: 4175 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT; 4176 case GL_STENCIL_EXT: 4177 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT; 4178 break; 4179 default: 4180 NOTREACHED(); 4181 break; 4182 } 4183 } 4184 } 4185 4186 // If the default framebuffer is bound but we are still rendering to an 4187 // FBO, translate attachment names that refer to default framebuffer 4188 // channels to corresponding framebuffer attachments. 4189 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]); 4190 for (GLsizei i = 0; i < numAttachments; ++i) { 4191 GLenum attachment = attachments[i]; 4192 if (!framebuffer && GetBackbufferServiceId()) { 4193 switch (attachment) { 4194 case GL_COLOR_EXT: 4195 attachment = GL_COLOR_ATTACHMENT0; 4196 break; 4197 case GL_DEPTH_EXT: 4198 attachment = GL_DEPTH_ATTACHMENT; 4199 break; 4200 case GL_STENCIL_EXT: 4201 attachment = GL_STENCIL_ATTACHMENT; 4202 break; 4203 default: 4204 NOTREACHED(); 4205 return; 4206 } 4207 } 4208 translated_attachments[i] = attachment; 4209 } 4210 4211 ScopedRenderTo do_render(framebuffer); 4212 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get()); 4213 } 4214 4215 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { 4216 if (state_.vertex_attrib_manager->Enable(index, true)) { 4217 glEnableVertexAttribArray(index); 4218 } else { 4219 LOCAL_SET_GL_ERROR( 4220 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range"); 4221 } 4222 } 4223 4224 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { 4225 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 4226 &state_, target); 4227 if (!texture_ref || 4228 !texture_manager()->CanGenerateMipmaps(texture_ref)) { 4229 LOCAL_SET_GL_ERROR( 4230 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips"); 4231 return; 4232 } 4233 4234 if (target == GL_TEXTURE_CUBE_MAP) { 4235 for (int i = 0; i < 6; ++i) { 4236 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; 4237 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) { 4238 LOCAL_SET_GL_ERROR( 4239 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big"); 4240 return; 4241 } 4242 } 4243 } else { 4244 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) { 4245 LOCAL_SET_GL_ERROR( 4246 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big"); 4247 return; 4248 } 4249 } 4250 4251 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap"); 4252 // Workaround for Mac driver bug. In the large scheme of things setting 4253 // glTexParamter twice for glGenerateMipmap is probably not a lage performance 4254 // hit so there's probably no need to make this conditional. The bug appears 4255 // to be that if the filtering mode is set to something that doesn't require 4256 // mipmaps for rendering, or is never set to something other than the default, 4257 // then glGenerateMipmap misbehaves. 4258 if (workarounds().set_texture_filter_before_generating_mipmap) { 4259 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 4260 } 4261 glGenerateMipmapEXT(target); 4262 if (workarounds().set_texture_filter_before_generating_mipmap) { 4263 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, 4264 texture_ref->texture()->min_filter()); 4265 } 4266 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap"); 4267 if (error == GL_NO_ERROR) { 4268 texture_manager()->MarkMipmapsGenerated(texture_ref); 4269 } 4270 } 4271 4272 bool GLES2DecoderImpl::GetHelper( 4273 GLenum pname, GLint* params, GLsizei* num_written) { 4274 DCHECK(num_written); 4275 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 4276 switch (pname) { 4277 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 4278 *num_written = 1; 4279 // Return the GL implementation's preferred format and (see below type) 4280 // if we have the GL extension that exposes this. This allows the GPU 4281 // client to use the implementation's preferred format for glReadPixels 4282 // for optimisation. 4283 // 4284 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error 4285 // case when requested on integer/floating point buffers but which is 4286 // acceptable on GLES2 and with the GL_OES_read_format extension. 4287 // 4288 // Therefore if an error occurs we swallow the error and use the 4289 // internal implementation. 4290 if (params) { 4291 if (context_->HasExtension("GL_OES_read_format")) { 4292 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper", 4293 GetErrorState()); 4294 glGetIntegerv(pname, params); 4295 if (glGetError() == GL_NO_ERROR) 4296 return true; 4297 } 4298 *params = GLES2Util::GetPreferredGLReadPixelsFormat( 4299 GetBoundReadFrameBufferInternalFormat()); 4300 } 4301 return true; 4302 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 4303 *num_written = 1; 4304 if (params) { 4305 if (context_->HasExtension("GL_OES_read_format")) { 4306 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper", 4307 GetErrorState()); 4308 glGetIntegerv(pname, params); 4309 if (glGetError() == GL_NO_ERROR) 4310 return true; 4311 } 4312 *params = GLES2Util::GetPreferredGLReadPixelsType( 4313 GetBoundReadFrameBufferInternalFormat(), 4314 GetBoundReadFrameBufferTextureType()); 4315 } 4316 return true; 4317 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 4318 *num_written = 1; 4319 if (params) { 4320 *params = group_->max_fragment_uniform_vectors(); 4321 } 4322 return true; 4323 case GL_MAX_VARYING_VECTORS: 4324 *num_written = 1; 4325 if (params) { 4326 *params = group_->max_varying_vectors(); 4327 } 4328 return true; 4329 case GL_MAX_VERTEX_UNIFORM_VECTORS: 4330 *num_written = 1; 4331 if (params) { 4332 *params = group_->max_vertex_uniform_vectors(); 4333 } 4334 return true; 4335 } 4336 } 4337 switch (pname) { 4338 case GL_MAX_VIEWPORT_DIMS: 4339 if (offscreen_target_frame_buffer_.get()) { 4340 *num_written = 2; 4341 if (params) { 4342 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 4343 params[1] = renderbuffer_manager()->max_renderbuffer_size(); 4344 } 4345 return true; 4346 } 4347 return false; 4348 case GL_MAX_SAMPLES: 4349 *num_written = 1; 4350 if (params) { 4351 params[0] = renderbuffer_manager()->max_samples(); 4352 } 4353 return true; 4354 case GL_MAX_RENDERBUFFER_SIZE: 4355 *num_written = 1; 4356 if (params) { 4357 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 4358 } 4359 return true; 4360 case GL_MAX_TEXTURE_SIZE: 4361 *num_written = 1; 4362 if (params) { 4363 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D); 4364 } 4365 return true; 4366 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 4367 *num_written = 1; 4368 if (params) { 4369 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP); 4370 } 4371 return true; 4372 case GL_MAX_COLOR_ATTACHMENTS_EXT: 4373 *num_written = 1; 4374 if (params) { 4375 params[0] = group_->max_color_attachments(); 4376 } 4377 return true; 4378 case GL_MAX_DRAW_BUFFERS_ARB: 4379 *num_written = 1; 4380 if (params) { 4381 params[0] = group_->max_draw_buffers(); 4382 } 4383 return true; 4384 case GL_ALPHA_BITS: 4385 *num_written = 1; 4386 if (params) { 4387 GLint v = 0; 4388 glGetIntegerv(GL_ALPHA_BITS, &v); 4389 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0; 4390 } 4391 return true; 4392 case GL_DEPTH_BITS: 4393 *num_written = 1; 4394 if (params) { 4395 GLint v = 0; 4396 glGetIntegerv(GL_DEPTH_BITS, &v); 4397 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0; 4398 } 4399 return true; 4400 case GL_STENCIL_BITS: 4401 *num_written = 1; 4402 if (params) { 4403 GLint v = 0; 4404 glGetIntegerv(GL_STENCIL_BITS, &v); 4405 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0; 4406 } 4407 return true; 4408 case GL_COMPRESSED_TEXTURE_FORMATS: 4409 *num_written = validators_->compressed_texture_format.GetValues().size(); 4410 if (params) { 4411 for (GLint ii = 0; ii < *num_written; ++ii) { 4412 params[ii] = validators_->compressed_texture_format.GetValues()[ii]; 4413 } 4414 } 4415 return true; 4416 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 4417 *num_written = 1; 4418 if (params) { 4419 *params = validators_->compressed_texture_format.GetValues().size(); 4420 } 4421 return true; 4422 case GL_NUM_SHADER_BINARY_FORMATS: 4423 *num_written = 1; 4424 if (params) { 4425 *params = validators_->shader_binary_format.GetValues().size(); 4426 } 4427 return true; 4428 case GL_SHADER_BINARY_FORMATS: 4429 *num_written = validators_->shader_binary_format.GetValues().size(); 4430 if (params) { 4431 for (GLint ii = 0; ii < *num_written; ++ii) { 4432 params[ii] = validators_->shader_binary_format.GetValues()[ii]; 4433 } 4434 } 4435 return true; 4436 case GL_SHADER_COMPILER: 4437 *num_written = 1; 4438 if (params) { 4439 *params = GL_TRUE; 4440 } 4441 return true; 4442 case GL_ARRAY_BUFFER_BINDING: 4443 *num_written = 1; 4444 if (params) { 4445 if (state_.bound_array_buffer.get()) { 4446 GLuint client_id = 0; 4447 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(), 4448 &client_id); 4449 *params = client_id; 4450 } else { 4451 *params = 0; 4452 } 4453 } 4454 return true; 4455 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 4456 *num_written = 1; 4457 if (params) { 4458 if (state_.vertex_attrib_manager->element_array_buffer()) { 4459 GLuint client_id = 0; 4460 buffer_manager()->GetClientId( 4461 state_.vertex_attrib_manager->element_array_buffer()-> 4462 service_id(), &client_id); 4463 *params = client_id; 4464 } else { 4465 *params = 0; 4466 } 4467 } 4468 return true; 4469 case GL_FRAMEBUFFER_BINDING: 4470 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) 4471 *num_written = 1; 4472 if (params) { 4473 Framebuffer* framebuffer = 4474 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4475 if (framebuffer) { 4476 GLuint client_id = 0; 4477 framebuffer_manager()->GetClientId( 4478 framebuffer->service_id(), &client_id); 4479 *params = client_id; 4480 } else { 4481 *params = 0; 4482 } 4483 } 4484 return true; 4485 case GL_READ_FRAMEBUFFER_BINDING_EXT: 4486 *num_written = 1; 4487 if (params) { 4488 Framebuffer* framebuffer = 4489 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 4490 if (framebuffer) { 4491 GLuint client_id = 0; 4492 framebuffer_manager()->GetClientId( 4493 framebuffer->service_id(), &client_id); 4494 *params = client_id; 4495 } else { 4496 *params = 0; 4497 } 4498 } 4499 return true; 4500 case GL_RENDERBUFFER_BINDING: 4501 *num_written = 1; 4502 if (params) { 4503 Renderbuffer* renderbuffer = 4504 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4505 if (renderbuffer) { 4506 *params = renderbuffer->client_id(); 4507 } else { 4508 *params = 0; 4509 } 4510 } 4511 return true; 4512 case GL_CURRENT_PROGRAM: 4513 *num_written = 1; 4514 if (params) { 4515 if (state_.current_program.get()) { 4516 GLuint client_id = 0; 4517 program_manager()->GetClientId( 4518 state_.current_program->service_id(), &client_id); 4519 *params = client_id; 4520 } else { 4521 *params = 0; 4522 } 4523 } 4524 return true; 4525 case GL_VERTEX_ARRAY_BINDING_OES: 4526 *num_written = 1; 4527 if (params) { 4528 if (state_.vertex_attrib_manager.get() != 4529 state_.default_vertex_attrib_manager.get()) { 4530 GLuint client_id = 0; 4531 vertex_array_manager_->GetClientId( 4532 state_.vertex_attrib_manager->service_id(), &client_id); 4533 *params = client_id; 4534 } else { 4535 *params = 0; 4536 } 4537 } 4538 return true; 4539 case GL_TEXTURE_BINDING_2D: 4540 *num_written = 1; 4541 if (params) { 4542 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4543 if (unit.bound_texture_2d.get()) { 4544 *params = unit.bound_texture_2d->client_id(); 4545 } else { 4546 *params = 0; 4547 } 4548 } 4549 return true; 4550 case GL_TEXTURE_BINDING_CUBE_MAP: 4551 *num_written = 1; 4552 if (params) { 4553 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4554 if (unit.bound_texture_cube_map.get()) { 4555 *params = unit.bound_texture_cube_map->client_id(); 4556 } else { 4557 *params = 0; 4558 } 4559 } 4560 return true; 4561 case GL_TEXTURE_BINDING_EXTERNAL_OES: 4562 *num_written = 1; 4563 if (params) { 4564 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4565 if (unit.bound_texture_external_oes.get()) { 4566 *params = unit.bound_texture_external_oes->client_id(); 4567 } else { 4568 *params = 0; 4569 } 4570 } 4571 return true; 4572 case GL_TEXTURE_BINDING_RECTANGLE_ARB: 4573 *num_written = 1; 4574 if (params) { 4575 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 4576 if (unit.bound_texture_rectangle_arb.get()) { 4577 *params = unit.bound_texture_rectangle_arb->client_id(); 4578 } else { 4579 *params = 0; 4580 } 4581 } 4582 return true; 4583 case GL_UNPACK_FLIP_Y_CHROMIUM: 4584 *num_written = 1; 4585 if (params) { 4586 params[0] = unpack_flip_y_; 4587 } 4588 return true; 4589 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 4590 *num_written = 1; 4591 if (params) { 4592 params[0] = unpack_premultiply_alpha_; 4593 } 4594 return true; 4595 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 4596 *num_written = 1; 4597 if (params) { 4598 params[0] = unpack_unpremultiply_alpha_; 4599 } 4600 return true; 4601 case GL_BIND_GENERATES_RESOURCE_CHROMIUM: 4602 *num_written = 1; 4603 if (params) { 4604 params[0] = group_->bind_generates_resource() ? 1 : 0; 4605 } 4606 return true; 4607 default: 4608 if (pname >= GL_DRAW_BUFFER0_ARB && 4609 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) { 4610 *num_written = 1; 4611 if (params) { 4612 Framebuffer* framebuffer = 4613 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 4614 if (framebuffer) { 4615 params[0] = framebuffer->GetDrawBuffer(pname); 4616 } else { // backbuffer 4617 if (pname == GL_DRAW_BUFFER0_ARB) 4618 params[0] = group_->draw_buffer(); 4619 else 4620 params[0] = GL_NONE; 4621 } 4622 } 4623 return true; 4624 } 4625 *num_written = util_.GLGetNumValuesReturned(pname); 4626 return false; 4627 } 4628 } 4629 4630 bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( 4631 GLenum pname, GLsizei* num_values) { 4632 if (state_.GetStateAsGLint(pname, NULL, num_values)) { 4633 return true; 4634 } 4635 return GetHelper(pname, NULL, num_values); 4636 } 4637 4638 GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) { 4639 if (GL_MAX_SAMPLES == pname && 4640 features().use_img_for_multisampled_render_to_texture) { 4641 return GL_MAX_SAMPLES_IMG; 4642 } 4643 return pname; 4644 } 4645 4646 void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { 4647 DCHECK(params); 4648 GLsizei num_written = 0; 4649 if (GetNumValuesReturnedForGLGet(pname, &num_written)) { 4650 scoped_ptr<GLint[]> values(new GLint[num_written]); 4651 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) { 4652 GetHelper(pname, values.get(), &num_written); 4653 } 4654 for (GLsizei ii = 0; ii < num_written; ++ii) { 4655 params[ii] = static_cast<GLboolean>(values[ii]); 4656 } 4657 } else { 4658 pname = AdjustGetPname(pname); 4659 glGetBooleanv(pname, params); 4660 } 4661 } 4662 4663 void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { 4664 DCHECK(params); 4665 GLsizei num_written = 0; 4666 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) { 4667 if (GetHelper(pname, NULL, &num_written)) { 4668 scoped_ptr<GLint[]> values(new GLint[num_written]); 4669 GetHelper(pname, values.get(), &num_written); 4670 for (GLsizei ii = 0; ii < num_written; ++ii) { 4671 params[ii] = static_cast<GLfloat>(values[ii]); 4672 } 4673 } else { 4674 pname = AdjustGetPname(pname); 4675 glGetFloatv(pname, params); 4676 } 4677 } 4678 } 4679 4680 void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { 4681 DCHECK(params); 4682 GLsizei num_written; 4683 if (!state_.GetStateAsGLint(pname, params, &num_written) && 4684 !GetHelper(pname, params, &num_written)) { 4685 pname = AdjustGetPname(pname); 4686 glGetIntegerv(pname, params); 4687 } 4688 } 4689 4690 void GLES2DecoderImpl::DoGetProgramiv( 4691 GLuint program_id, GLenum pname, GLint* params) { 4692 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv"); 4693 if (!program) { 4694 return; 4695 } 4696 program->GetProgramiv(pname, params); 4697 } 4698 4699 void GLES2DecoderImpl::DoGetBufferParameteriv( 4700 GLenum target, GLenum pname, GLint* params) { 4701 // Just delegate it. Some validation is actually done before this. 4702 buffer_manager()->ValidateAndDoGetBufferParameteriv( 4703 &state_, target, pname, params); 4704 } 4705 4706 void GLES2DecoderImpl::DoBindAttribLocation( 4707 GLuint program_id, GLuint index, const char* name) { 4708 if (!StringIsValidForGLES(name)) { 4709 LOCAL_SET_GL_ERROR( 4710 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); 4711 return; 4712 } 4713 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4714 LOCAL_SET_GL_ERROR( 4715 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); 4716 return; 4717 } 4718 if (index >= group_->max_vertex_attribs()) { 4719 LOCAL_SET_GL_ERROR( 4720 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range"); 4721 return; 4722 } 4723 Program* program = GetProgramInfoNotShader( 4724 program_id, "glBindAttribLocation"); 4725 if (!program) { 4726 return; 4727 } 4728 program->SetAttribLocationBinding(name, static_cast<GLint>(index)); 4729 glBindAttribLocation(program->service_id(), index, name); 4730 } 4731 4732 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( 4733 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) { 4734 GLuint program = static_cast<GLuint>(c.program); 4735 GLuint index = static_cast<GLuint>(c.index); 4736 Bucket* bucket = GetBucket(c.name_bucket_id); 4737 if (!bucket || bucket->size() == 0) { 4738 return error::kInvalidArguments; 4739 } 4740 std::string name_str; 4741 if (!bucket->GetAsString(&name_str)) { 4742 return error::kInvalidArguments; 4743 } 4744 DoBindAttribLocation(program, index, name_str.c_str()); 4745 return error::kNoError; 4746 } 4747 4748 void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM( 4749 GLuint program_id, GLint location, const char* name) { 4750 if (!StringIsValidForGLES(name)) { 4751 LOCAL_SET_GL_ERROR( 4752 GL_INVALID_VALUE, 4753 "glBindUniformLocationCHROMIUM", "Invalid character"); 4754 return; 4755 } 4756 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4757 LOCAL_SET_GL_ERROR( 4758 GL_INVALID_OPERATION, 4759 "glBindUniformLocationCHROMIUM", "reserved prefix"); 4760 return; 4761 } 4762 if (location < 0 || static_cast<uint32>(location) >= 4763 (group_->max_fragment_uniform_vectors() + 4764 group_->max_vertex_uniform_vectors()) * 4) { 4765 LOCAL_SET_GL_ERROR( 4766 GL_INVALID_VALUE, 4767 "glBindUniformLocationCHROMIUM", "location out of range"); 4768 return; 4769 } 4770 Program* program = GetProgramInfoNotShader( 4771 program_id, "glBindUniformLocationCHROMIUM"); 4772 if (!program) { 4773 return; 4774 } 4775 if (!program->SetUniformLocationBinding(name, location)) { 4776 LOCAL_SET_GL_ERROR( 4777 GL_INVALID_VALUE, 4778 "glBindUniformLocationCHROMIUM", "location out of range"); 4779 } 4780 } 4781 4782 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket( 4783 uint32 immediate_data_size, 4784 const cmds::BindUniformLocationCHROMIUMBucket& c) { 4785 GLuint program = static_cast<GLuint>(c.program); 4786 GLint location = static_cast<GLint>(c.location); 4787 Bucket* bucket = GetBucket(c.name_bucket_id); 4788 if (!bucket || bucket->size() == 0) { 4789 return error::kInvalidArguments; 4790 } 4791 std::string name_str; 4792 if (!bucket->GetAsString(&name_str)) { 4793 return error::kInvalidArguments; 4794 } 4795 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4796 return error::kNoError; 4797 } 4798 4799 error::Error GLES2DecoderImpl::HandleDeleteShader( 4800 uint32 immediate_data_size, const cmds::DeleteShader& c) { 4801 GLuint client_id = c.shader; 4802 if (client_id) { 4803 Shader* shader = GetShader(client_id); 4804 if (shader) { 4805 if (!shader->IsDeleted()) { 4806 glDeleteShader(shader->service_id()); 4807 shader_manager()->MarkAsDeleted(shader); 4808 } 4809 } else { 4810 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader"); 4811 } 4812 } 4813 return error::kNoError; 4814 } 4815 4816 error::Error GLES2DecoderImpl::HandleDeleteProgram( 4817 uint32 immediate_data_size, const cmds::DeleteProgram& c) { 4818 GLuint client_id = c.program; 4819 if (client_id) { 4820 Program* program = GetProgram(client_id); 4821 if (program) { 4822 if (!program->IsDeleted()) { 4823 program_manager()->MarkAsDeleted(shader_manager(), program); 4824 } 4825 } else { 4826 LOCAL_SET_GL_ERROR( 4827 GL_INVALID_VALUE, "glDeleteProgram", "unknown program"); 4828 } 4829 } 4830 return error::kNoError; 4831 } 4832 4833 void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM( 4834 GLuint namespace_id, GLsizei n, const GLuint* ids) { 4835 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4836 for (GLsizei ii = 0; ii < n; ++ii) { 4837 id_allocator->FreeID(ids[ii]); 4838 } 4839 } 4840 4841 error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM( 4842 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) { 4843 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4844 GLsizei n = static_cast<GLsizei>(c.n); 4845 uint32 data_size; 4846 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4847 return error::kOutOfBounds; 4848 } 4849 const GLuint* ids = GetSharedMemoryAs<const GLuint*>( 4850 c.ids_shm_id, c.ids_shm_offset, data_size); 4851 if (n < 0) { 4852 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0"); 4853 return error::kNoError; 4854 } 4855 if (ids == NULL) { 4856 return error::kOutOfBounds; 4857 } 4858 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids); 4859 return error::kNoError; 4860 } 4861 4862 void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM( 4863 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { 4864 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4865 if (id_offset == 0) { 4866 for (GLsizei ii = 0; ii < n; ++ii) { 4867 ids[ii] = id_allocator->AllocateID(); 4868 } 4869 } else { 4870 for (GLsizei ii = 0; ii < n; ++ii) { 4871 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset); 4872 id_offset = ids[ii] + 1; 4873 } 4874 } 4875 } 4876 4877 error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM( 4878 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) { 4879 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4880 GLuint id_offset = static_cast<GLuint>(c.id_offset); 4881 GLsizei n = static_cast<GLsizei>(c.n); 4882 uint32 data_size; 4883 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4884 return error::kOutOfBounds; 4885 } 4886 GLuint* ids = GetSharedMemoryAs<GLuint*>( 4887 c.ids_shm_id, c.ids_shm_offset, data_size); 4888 if (n < 0) { 4889 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0"); 4890 return error::kNoError; 4891 } 4892 if (ids == NULL) { 4893 return error::kOutOfBounds; 4894 } 4895 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids); 4896 return error::kNoError; 4897 } 4898 4899 void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM( 4900 GLuint namespace_id, GLsizei n, const GLuint* ids) { 4901 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4902 for (GLsizei ii = 0; ii < n; ++ii) { 4903 if (!id_allocator->MarkAsUsed(ids[ii])) { 4904 for (GLsizei jj = 0; jj < ii; ++jj) { 4905 id_allocator->FreeID(ids[jj]); 4906 } 4907 LOCAL_SET_GL_ERROR( 4908 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", 4909 "attempt to register id that already exists"); 4910 return; 4911 } 4912 } 4913 } 4914 4915 error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM( 4916 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) { 4917 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4918 GLsizei n = static_cast<GLsizei>(c.n); 4919 uint32 data_size; 4920 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4921 return error::kOutOfBounds; 4922 } 4923 GLuint* ids = GetSharedMemoryAs<GLuint*>( 4924 c.ids_shm_id, c.ids_shm_offset, data_size); 4925 if (n < 0) { 4926 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0"); 4927 return error::kNoError; 4928 } 4929 if (ids == NULL) { 4930 return error::kOutOfBounds; 4931 } 4932 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids); 4933 return error::kNoError; 4934 } 4935 4936 error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { 4937 DCHECK(!ShouldDeferDraws()); 4938 if (CheckBoundFramebuffersValid("glClear")) { 4939 ApplyDirtyState(); 4940 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 4941 glClear(mask); 4942 } 4943 return error::kNoError; 4944 } 4945 4946 void GLES2DecoderImpl::DoFramebufferRenderbuffer( 4947 GLenum target, GLenum attachment, GLenum renderbuffertarget, 4948 GLuint client_renderbuffer_id) { 4949 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 4950 if (!framebuffer) { 4951 LOCAL_SET_GL_ERROR( 4952 GL_INVALID_OPERATION, 4953 "glFramebufferRenderbuffer", "no framebuffer bound"); 4954 return; 4955 } 4956 GLuint service_id = 0; 4957 Renderbuffer* renderbuffer = NULL; 4958 if (client_renderbuffer_id) { 4959 renderbuffer = GetRenderbuffer(client_renderbuffer_id); 4960 if (!renderbuffer) { 4961 LOCAL_SET_GL_ERROR( 4962 GL_INVALID_OPERATION, 4963 "glFramebufferRenderbuffer", "unknown renderbuffer"); 4964 return; 4965 } 4966 service_id = renderbuffer->service_id(); 4967 } 4968 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer"); 4969 glFramebufferRenderbufferEXT( 4970 target, attachment, renderbuffertarget, service_id); 4971 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer"); 4972 if (error == GL_NO_ERROR) { 4973 framebuffer->AttachRenderbuffer(attachment, renderbuffer); 4974 } 4975 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { 4976 framebuffer_state_.clear_state_dirty = true; 4977 } 4978 OnFboChanged(); 4979 } 4980 4981 void GLES2DecoderImpl::DoDisable(GLenum cap) { 4982 if (SetCapabilityState(cap, false)) { 4983 glDisable(cap); 4984 } 4985 } 4986 4987 void GLES2DecoderImpl::DoEnable(GLenum cap) { 4988 if (SetCapabilityState(cap, true)) { 4989 glEnable(cap); 4990 } 4991 } 4992 4993 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) { 4994 state_.z_near = std::min(1.0f, std::max(0.0f, znear)); 4995 state_.z_far = std::min(1.0f, std::max(0.0f, zfar)); 4996 glDepthRange(znear, zfar); 4997 } 4998 4999 void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) { 5000 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value)); 5001 state_.sample_coverage_invert = (invert != 0); 5002 glSampleCoverage(state_.sample_coverage_value, invert); 5003 } 5004 5005 // Assumes framebuffer is complete. 5006 void GLES2DecoderImpl::ClearUnclearedAttachments( 5007 GLenum target, Framebuffer* framebuffer) { 5008 if (target == GL_READ_FRAMEBUFFER_EXT) { 5009 // bind this to the DRAW point, clear then bind back to READ 5010 // TODO(gman): I don't think there is any guarantee that an FBO that 5011 // is complete on the READ attachment will be complete as a DRAW 5012 // attachment. 5013 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); 5014 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id()); 5015 } 5016 GLbitfield clear_bits = 0; 5017 if (framebuffer->HasUnclearedColorAttachments()) { 5018 glClearColor( 5019 0.0f, 0.0f, 0.0f, 5020 (GLES2Util::GetChannelsForFormat( 5021 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 5022 1.0f); 5023 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 5024 clear_bits |= GL_COLOR_BUFFER_BIT; 5025 if (feature_info_->feature_flags().ext_draw_buffers) 5026 framebuffer->PrepareDrawBuffersForClear(); 5027 } 5028 5029 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || 5030 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 5031 glClearStencil(0); 5032 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1); 5033 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1); 5034 clear_bits |= GL_STENCIL_BUFFER_BIT; 5035 } 5036 5037 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || 5038 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 5039 glClearDepth(1.0f); 5040 state_.SetDeviceDepthMask(GL_TRUE); 5041 clear_bits |= GL_DEPTH_BUFFER_BIT; 5042 } 5043 5044 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 5045 glClear(clear_bits); 5046 5047 if ((clear_bits | GL_COLOR_BUFFER_BIT) != 0 && 5048 feature_info_->feature_flags().ext_draw_buffers) 5049 framebuffer->RestoreDrawBuffersAfterClear(); 5050 5051 framebuffer_manager()->MarkAttachmentsAsCleared( 5052 framebuffer, renderbuffer_manager(), texture_manager()); 5053 5054 RestoreClearState(); 5055 5056 if (target == GL_READ_FRAMEBUFFER_EXT) { 5057 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id()); 5058 Framebuffer* draw_framebuffer = 5059 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 5060 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() : 5061 GetBackbufferServiceId(); 5062 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id); 5063 } 5064 } 5065 5066 void GLES2DecoderImpl::RestoreClearState() { 5067 framebuffer_state_.clear_state_dirty = true; 5068 glClearColor( 5069 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue, 5070 state_.color_clear_alpha); 5071 glClearStencil(state_.stencil_clear); 5072 glClearDepth(state_.depth_clear); 5073 if (state_.enable_flags.scissor_test) { 5074 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); 5075 } 5076 } 5077 5078 GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { 5079 Framebuffer* framebuffer = 5080 GetFramebufferInfoForTarget(target); 5081 if (!framebuffer) { 5082 return GL_FRAMEBUFFER_COMPLETE; 5083 } 5084 GLenum completeness = framebuffer->IsPossiblyComplete(); 5085 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 5086 return completeness; 5087 } 5088 return framebuffer->GetStatus(texture_manager(), target); 5089 } 5090 5091 void GLES2DecoderImpl::DoFramebufferTexture2D( 5092 GLenum target, GLenum attachment, GLenum textarget, 5093 GLuint client_texture_id, GLint level) { 5094 DoFramebufferTexture2DCommon( 5095 "glFramebufferTexture2D", target, attachment, 5096 textarget, client_texture_id, level, 0); 5097 } 5098 5099 void GLES2DecoderImpl::DoFramebufferTexture2DMultisample( 5100 GLenum target, GLenum attachment, GLenum textarget, 5101 GLuint client_texture_id, GLint level, GLsizei samples) { 5102 DoFramebufferTexture2DCommon( 5103 "glFramebufferTexture2DMultisample", target, attachment, 5104 textarget, client_texture_id, level, samples); 5105 } 5106 5107 void GLES2DecoderImpl::DoFramebufferTexture2DCommon( 5108 const char* name, GLenum target, GLenum attachment, GLenum textarget, 5109 GLuint client_texture_id, GLint level, GLsizei samples) { 5110 if (samples > renderbuffer_manager()->max_samples()) { 5111 LOCAL_SET_GL_ERROR( 5112 GL_INVALID_VALUE, 5113 "glFramebufferTexture2DMultisample", "samples too large"); 5114 return; 5115 } 5116 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 5117 if (!framebuffer) { 5118 LOCAL_SET_GL_ERROR( 5119 GL_INVALID_OPERATION, 5120 name, "no framebuffer bound."); 5121 return; 5122 } 5123 GLuint service_id = 0; 5124 TextureRef* texture_ref = NULL; 5125 if (client_texture_id) { 5126 texture_ref = GetTexture(client_texture_id); 5127 if (!texture_ref) { 5128 LOCAL_SET_GL_ERROR( 5129 GL_INVALID_OPERATION, 5130 name, "unknown texture_ref"); 5131 return; 5132 } 5133 service_id = texture_ref->service_id(); 5134 } 5135 5136 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) { 5137 LOCAL_SET_GL_ERROR( 5138 GL_INVALID_VALUE, 5139 name, "level out of range"); 5140 return; 5141 } 5142 5143 if (texture_ref) 5144 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget); 5145 5146 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name); 5147 if (0 == samples) { 5148 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); 5149 } else { 5150 if (features().use_img_for_multisampled_render_to_texture) { 5151 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, 5152 service_id, level, samples); 5153 } else { 5154 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, 5155 service_id, level, samples); 5156 } 5157 } 5158 GLenum error = LOCAL_PEEK_GL_ERROR(name); 5159 if (error == GL_NO_ERROR) { 5160 framebuffer->AttachTexture(attachment, texture_ref, textarget, level, 5161 samples); 5162 } 5163 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { 5164 framebuffer_state_.clear_state_dirty = true; 5165 } 5166 5167 if (texture_ref) 5168 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget); 5169 5170 OnFboChanged(); 5171 } 5172 5173 void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( 5174 GLenum target, GLenum attachment, GLenum pname, GLint* params) { 5175 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target); 5176 if (!framebuffer) { 5177 LOCAL_SET_GL_ERROR( 5178 GL_INVALID_OPERATION, 5179 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound"); 5180 return; 5181 } 5182 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { 5183 const Framebuffer::Attachment* attachment_object = 5184 framebuffer->GetAttachment(attachment); 5185 *params = attachment_object ? attachment_object->object_name() : 0; 5186 } else { 5187 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT && 5188 features().use_img_for_multisampled_render_to_texture) { 5189 pname = GL_TEXTURE_SAMPLES_IMG; 5190 } 5191 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); 5192 } 5193 } 5194 5195 void GLES2DecoderImpl::DoGetRenderbufferParameteriv( 5196 GLenum target, GLenum pname, GLint* params) { 5197 Renderbuffer* renderbuffer = 5198 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5199 if (!renderbuffer) { 5200 LOCAL_SET_GL_ERROR( 5201 GL_INVALID_OPERATION, 5202 "glGetRenderbufferParameteriv", "no renderbuffer bound"); 5203 return; 5204 } 5205 switch (pname) { 5206 case GL_RENDERBUFFER_INTERNAL_FORMAT: 5207 *params = renderbuffer->internal_format(); 5208 break; 5209 case GL_RENDERBUFFER_WIDTH: 5210 *params = renderbuffer->width(); 5211 break; 5212 case GL_RENDERBUFFER_HEIGHT: 5213 *params = renderbuffer->height(); 5214 break; 5215 case GL_RENDERBUFFER_SAMPLES_EXT: 5216 if (features().use_img_for_multisampled_render_to_texture) { 5217 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG, 5218 params); 5219 } else { 5220 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT, 5221 params); 5222 } 5223 default: 5224 glGetRenderbufferParameterivEXT(target, pname, params); 5225 break; 5226 } 5227 } 5228 5229 void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM( 5230 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 5231 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 5232 GLbitfield mask, GLenum filter) { 5233 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws()); 5234 5235 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) { 5236 return; 5237 } 5238 5239 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 5240 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 5241 BlitFramebufferHelper( 5242 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5243 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, 5244 state_.enable_flags.scissor_test); 5245 } 5246 5247 void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper( 5248 const FeatureInfo* feature_info, 5249 GLenum target, 5250 GLsizei samples, 5251 GLenum internal_format, 5252 GLsizei width, 5253 GLsizei height) { 5254 // TODO(sievers): This could be resolved at the GL binding level, but the 5255 // binding process is currently a bit too 'brute force'. 5256 if (feature_info->feature_flags().is_angle) { 5257 glRenderbufferStorageMultisampleANGLE( 5258 target, samples, internal_format, width, height); 5259 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) { 5260 glRenderbufferStorageMultisample( 5261 target, samples, internal_format, width, height); 5262 } else { 5263 glRenderbufferStorageMultisampleEXT( 5264 target, samples, internal_format, width, height); 5265 } 5266 } 5267 5268 void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0, 5269 GLint srcY0, 5270 GLint srcX1, 5271 GLint srcY1, 5272 GLint dstX0, 5273 GLint dstY0, 5274 GLint dstX1, 5275 GLint dstY1, 5276 GLbitfield mask, 5277 GLenum filter) { 5278 // TODO(sievers): This could be resolved at the GL binding level, but the 5279 // binding process is currently a bit too 'brute force'. 5280 if (feature_info_->feature_flags().is_angle) { 5281 glBlitFramebufferANGLE( 5282 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5283 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) { 5284 glBlitFramebuffer( 5285 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5286 } else { 5287 glBlitFramebufferEXT( 5288 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 5289 } 5290 } 5291 5292 bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample( 5293 GLsizei samples, 5294 GLenum internalformat, 5295 GLsizei width, 5296 GLsizei height) { 5297 if (samples > renderbuffer_manager()->max_samples()) { 5298 LOCAL_SET_GL_ERROR( 5299 GL_INVALID_VALUE, 5300 "glRenderbufferStorageMultisample", "samples too large"); 5301 return false; 5302 } 5303 5304 if (width > renderbuffer_manager()->max_renderbuffer_size() || 5305 height > renderbuffer_manager()->max_renderbuffer_size()) { 5306 LOCAL_SET_GL_ERROR( 5307 GL_INVALID_VALUE, 5308 "glRenderbufferStorageMultisample", "dimensions too large"); 5309 return false; 5310 } 5311 5312 uint32 estimated_size = 0; 5313 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize( 5314 width, height, samples, internalformat, &estimated_size)) { 5315 LOCAL_SET_GL_ERROR( 5316 GL_OUT_OF_MEMORY, 5317 "glRenderbufferStorageMultisample", "dimensions too large"); 5318 return false; 5319 } 5320 5321 if (!EnsureGPUMemoryAvailable(estimated_size)) { 5322 LOCAL_SET_GL_ERROR( 5323 GL_OUT_OF_MEMORY, 5324 "glRenderbufferStorageMultisample", "out of memory"); 5325 return false; 5326 } 5327 5328 return true; 5329 } 5330 5331 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM( 5332 GLenum target, GLsizei samples, GLenum internalformat, 5333 GLsizei width, GLsizei height) { 5334 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5335 if (!renderbuffer) { 5336 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 5337 "glRenderbufferStorageMultisampleCHROMIUM", 5338 "no renderbuffer bound"); 5339 return; 5340 } 5341 5342 if (!ValidateRenderbufferStorageMultisample( 5343 samples, internalformat, width, height)) { 5344 return; 5345 } 5346 5347 GLenum impl_format = 5348 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( 5349 internalformat); 5350 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER( 5351 "glRenderbufferStorageMultisampleCHROMIUM"); 5352 RenderbufferStorageMultisampleHelper( 5353 feature_info_, target, samples, impl_format, width, height); 5354 GLenum error = 5355 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM"); 5356 if (error == GL_NO_ERROR) { 5357 5358 if (workarounds().validate_multisample_buffer_allocation) { 5359 if (!VerifyMultisampleRenderbufferIntegrity( 5360 renderbuffer->service_id(), impl_format)) { 5361 LOCAL_SET_GL_ERROR( 5362 GL_OUT_OF_MEMORY, 5363 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory"); 5364 return; 5365 } 5366 } 5367 5368 // TODO(gman): If renderbuffers tracked which framebuffers they were 5369 // attached to we could just mark those framebuffers as not complete. 5370 framebuffer_manager()->IncFramebufferStateChangeCount(); 5371 renderbuffer_manager()->SetInfo( 5372 renderbuffer, samples, internalformat, width, height); 5373 } 5374 } 5375 5376 // This is the handler for multisampled_render_to_texture extensions. 5377 void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT( 5378 GLenum target, GLsizei samples, GLenum internalformat, 5379 GLsizei width, GLsizei height) { 5380 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5381 if (!renderbuffer) { 5382 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 5383 "glRenderbufferStorageMultisampleEXT", 5384 "no renderbuffer bound"); 5385 return; 5386 } 5387 5388 if (!ValidateRenderbufferStorageMultisample( 5389 samples, internalformat, width, height)) { 5390 return; 5391 } 5392 5393 GLenum impl_format = 5394 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( 5395 internalformat); 5396 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT"); 5397 if (features().use_img_for_multisampled_render_to_texture) { 5398 glRenderbufferStorageMultisampleIMG( 5399 target, samples, impl_format, width, height); 5400 } else { 5401 glRenderbufferStorageMultisampleEXT( 5402 target, samples, impl_format, width, height); 5403 } 5404 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT"); 5405 if (error == GL_NO_ERROR) { 5406 // TODO(gman): If renderbuffers tracked which framebuffers they were 5407 // attached to we could just mark those framebuffers as not complete. 5408 framebuffer_manager()->IncFramebufferStateChangeCount(); 5409 renderbuffer_manager()->SetInfo( 5410 renderbuffer, samples, internalformat, width, height); 5411 } 5412 } 5413 5414 // This function validates the allocation of a multisampled renderbuffer 5415 // by clearing it to a key color, blitting the contents to a texture, and 5416 // reading back the color to ensure it matches the key. 5417 bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity( 5418 GLuint renderbuffer, GLenum format) { 5419 5420 // Only validate color buffers. 5421 // These formats have been selected because they are very common or are known 5422 // to be used by the WebGL backbuffer. If problems are observed with other 5423 // color formats they can be added here. 5424 switch(format) { 5425 case GL_RGB: 5426 case GL_RGB8: 5427 case GL_RGBA: 5428 case GL_RGBA8: 5429 break; 5430 default: 5431 return true; 5432 } 5433 5434 GLint draw_framebuffer, read_framebuffer; 5435 5436 // Cache framebuffer and texture bindings. 5437 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer); 5438 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); 5439 5440 if (!validation_texture_) { 5441 GLint bound_texture; 5442 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture); 5443 5444 // Create additional resources needed for the verification. 5445 glGenTextures(1, &validation_texture_); 5446 glGenFramebuffersEXT(1, &validation_fbo_multisample_); 5447 glGenFramebuffersEXT(1, &validation_fbo_); 5448 5449 // Texture only needs to be 1x1. 5450 glBindTexture(GL_TEXTURE_2D, validation_texture_); 5451 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, 5452 GL_UNSIGNED_BYTE, NULL); 5453 5454 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); 5455 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5456 GL_TEXTURE_2D, validation_texture_, 0); 5457 5458 glBindTexture(GL_TEXTURE_2D, bound_texture); 5459 } 5460 5461 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_); 5462 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5463 GL_RENDERBUFFER, renderbuffer); 5464 5465 // Cache current state and reset it to the values we require. 5466 GLboolean scissor_enabled = false; 5467 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled); 5468 if (scissor_enabled) 5469 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 5470 5471 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; 5472 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask); 5473 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 5474 5475 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; 5476 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color); 5477 glClearColor(1.0f, 0.0f, 1.0f, 1.0f); 5478 5479 // Clear the buffer to the desired key color. 5480 glClear(GL_COLOR_BUFFER_BIT); 5481 5482 // Blit from the multisample buffer to a standard texture. 5483 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_); 5484 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_); 5485 5486 BlitFramebufferHelper( 5487 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST); 5488 5489 // Read a pixel from the buffer. 5490 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_); 5491 5492 unsigned char pixel[3] = {0, 0, 0}; 5493 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel); 5494 5495 // Detach the renderbuffer. 5496 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_); 5497 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5498 GL_RENDERBUFFER, 0); 5499 5500 // Restore cached state. 5501 if (scissor_enabled) 5502 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true); 5503 5504 state_.SetDeviceColorMask( 5505 color_mask[0], color_mask[1], color_mask[2], color_mask[3]); 5506 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); 5507 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer); 5508 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer); 5509 5510 // Return true if the pixel matched the desired key color. 5511 return (pixel[0] == 0xFF && 5512 pixel[1] == 0x00 && 5513 pixel[2] == 0xFF); 5514 } 5515 5516 void GLES2DecoderImpl::DoRenderbufferStorage( 5517 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { 5518 Renderbuffer* renderbuffer = 5519 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 5520 if (!renderbuffer) { 5521 LOCAL_SET_GL_ERROR( 5522 GL_INVALID_OPERATION, 5523 "glRenderbufferStorage", "no renderbuffer bound"); 5524 return; 5525 } 5526 5527 if (width > renderbuffer_manager()->max_renderbuffer_size() || 5528 height > renderbuffer_manager()->max_renderbuffer_size()) { 5529 LOCAL_SET_GL_ERROR( 5530 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large"); 5531 return; 5532 } 5533 5534 uint32 estimated_size = 0; 5535 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize( 5536 width, height, 1, internalformat, &estimated_size)) { 5537 LOCAL_SET_GL_ERROR( 5538 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large"); 5539 return; 5540 } 5541 5542 if (!EnsureGPUMemoryAvailable(estimated_size)) { 5543 LOCAL_SET_GL_ERROR( 5544 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory"); 5545 return; 5546 } 5547 5548 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage"); 5549 glRenderbufferStorageEXT( 5550 target, 5551 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat( 5552 internalformat), 5553 width, 5554 height); 5555 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage"); 5556 if (error == GL_NO_ERROR) { 5557 // TODO(gman): If tetxures tracked which framebuffers they were attached to 5558 // we could just mark those framebuffers as not complete. 5559 framebuffer_manager()->IncFramebufferStateChangeCount(); 5560 renderbuffer_manager()->SetInfo( 5561 renderbuffer, 1, internalformat, width, height); 5562 } 5563 } 5564 5565 void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) { 5566 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram"); 5567 Program* program = GetProgramInfoNotShader( 5568 program_id, "glLinkProgram"); 5569 if (!program) { 5570 return; 5571 } 5572 5573 LogClientServiceForInfo(program, program_id, "glLinkProgram"); 5574 ShaderTranslator* vertex_translator = NULL; 5575 ShaderTranslator* fragment_translator = NULL; 5576 if (use_shader_translator_) { 5577 vertex_translator = vertex_translator_.get(); 5578 fragment_translator = fragment_translator_.get(); 5579 } 5580 if (program->Link(shader_manager(), 5581 vertex_translator, 5582 fragment_translator, 5583 workarounds().count_all_in_varyings_packing ? 5584 Program::kCountAll : Program::kCountOnlyStaticallyUsed, 5585 shader_cache_callback_)) { 5586 if (program == state_.current_program.get()) { 5587 if (workarounds().use_current_program_after_successful_link) 5588 glUseProgram(program->service_id()); 5589 if (workarounds().clear_uniforms_before_first_program_use) 5590 program_manager()->ClearUniforms(program); 5591 } 5592 } 5593 }; 5594 5595 void GLES2DecoderImpl::DoTexParameterf( 5596 GLenum target, GLenum pname, GLfloat param) { 5597 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5598 &state_, target); 5599 if (!texture) { 5600 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture"); 5601 return; 5602 } 5603 5604 texture_manager()->SetParameterf( 5605 "glTexParameterf", GetErrorState(), texture, pname, param); 5606 } 5607 5608 void GLES2DecoderImpl::DoTexParameteri( 5609 GLenum target, GLenum pname, GLint param) { 5610 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5611 &state_, target); 5612 if (!texture) { 5613 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture"); 5614 return; 5615 } 5616 5617 texture_manager()->SetParameteri( 5618 "glTexParameteri", GetErrorState(), texture, pname, param); 5619 } 5620 5621 void GLES2DecoderImpl::DoTexParameterfv( 5622 GLenum target, GLenum pname, const GLfloat* params) { 5623 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5624 &state_, target); 5625 if (!texture) { 5626 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture"); 5627 return; 5628 } 5629 5630 texture_manager()->SetParameterf( 5631 "glTexParameterfv", GetErrorState(), texture, pname, *params); 5632 } 5633 5634 void GLES2DecoderImpl::DoTexParameteriv( 5635 GLenum target, GLenum pname, const GLint* params) { 5636 TextureRef* texture = texture_manager()->GetTextureInfoForTarget( 5637 &state_, target); 5638 if (!texture) { 5639 LOCAL_SET_GL_ERROR( 5640 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture"); 5641 return; 5642 } 5643 5644 texture_manager()->SetParameteri( 5645 "glTexParameteriv", GetErrorState(), texture, pname, *params); 5646 } 5647 5648 bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) { 5649 if (!state_.current_program.get()) { 5650 // The program does not exist. 5651 LOCAL_SET_GL_ERROR( 5652 GL_INVALID_OPERATION, function_name, "no program in use"); 5653 return false; 5654 } 5655 if (!state_.current_program->InUse()) { 5656 <