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 LOCAL_SET_GL_ERROR( 5657 GL_INVALID_OPERATION, function_name, "program not linked"); 5658 return false; 5659 } 5660 return true; 5661 } 5662 5663 bool GLES2DecoderImpl::CheckCurrentProgramForUniform( 5664 GLint location, const char* function_name) { 5665 if (!CheckCurrentProgram(function_name)) { 5666 return false; 5667 } 5668 return location != -1; 5669 } 5670 5671 bool GLES2DecoderImpl::PrepForSetUniformByLocation( 5672 GLint fake_location, 5673 const char* function_name, 5674 Program::UniformApiType api_type, 5675 GLint* real_location, 5676 GLenum* type, 5677 GLsizei* count) { 5678 DCHECK(type); 5679 DCHECK(count); 5680 DCHECK(real_location); 5681 5682 if (!CheckCurrentProgramForUniform(fake_location, function_name)) { 5683 return false; 5684 } 5685 GLint array_index = -1; 5686 const Program::UniformInfo* info = 5687 state_.current_program->GetUniformInfoByFakeLocation( 5688 fake_location, real_location, &array_index); 5689 if (!info) { 5690 LOCAL_SET_GL_ERROR( 5691 GL_INVALID_OPERATION, function_name, "unknown location"); 5692 return false; 5693 } 5694 5695 if ((api_type & info->accepts_api_type) == 0) { 5696 LOCAL_SET_GL_ERROR( 5697 GL_INVALID_OPERATION, function_name, 5698 "wrong uniform function for type"); 5699 return false; 5700 } 5701 if (*count > 1 && !info->is_array) { 5702 LOCAL_SET_GL_ERROR( 5703 GL_INVALID_OPERATION, function_name, "count > 1 for non-array"); 5704 return false; 5705 } 5706 *count = std::min(info->size - array_index, *count); 5707 if (*count <= 0) { 5708 return false; 5709 } 5710 *type = info->type; 5711 return true; 5712 } 5713 5714 void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) { 5715 GLenum type = 0; 5716 GLsizei count = 1; 5717 GLint real_location = -1; 5718 if (!PrepForSetUniformByLocation(fake_location, 5719 "glUniform1i", 5720 Program::kUniform1i, 5721 &real_location, 5722 &type, 5723 &count)) { 5724 return; 5725 } 5726 if (!state_.current_program->SetSamplers( 5727 state_.texture_units.size(), fake_location, 1, &v0)) { 5728 LOCAL_SET_GL_ERROR( 5729 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range"); 5730 return; 5731 } 5732 glUniform1i(real_location, v0); 5733 } 5734 5735 void GLES2DecoderImpl::DoUniform1iv( 5736 GLint fake_location, GLsizei count, const GLint *value) { 5737 GLenum type = 0; 5738 GLint real_location = -1; 5739 if (!PrepForSetUniformByLocation(fake_location, 5740 "glUniform1iv", 5741 Program::kUniform1i, 5742 &real_location, 5743 &type, 5744 &count)) { 5745 return; 5746 } 5747 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB || 5748 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) { 5749 if (!state_.current_program->SetSamplers( 5750 state_.texture_units.size(), fake_location, count, value)) { 5751 LOCAL_SET_GL_ERROR( 5752 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range"); 5753 return; 5754 } 5755 } 5756 glUniform1iv(real_location, count, value); 5757 } 5758 5759 void GLES2DecoderImpl::DoUniform1fv( 5760 GLint fake_location, GLsizei count, const GLfloat* value) { 5761 GLenum type = 0; 5762 GLint real_location = -1; 5763 if (!PrepForSetUniformByLocation(fake_location, 5764 "glUniform1fv", 5765 Program::kUniform1f, 5766 &real_location, 5767 &type, 5768 &count)) { 5769 return; 5770 } 5771 if (type == GL_BOOL) { 5772 scoped_ptr<GLint[]> temp(new GLint[count]); 5773 for (GLsizei ii = 0; ii < count; ++ii) { 5774 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5775 } 5776 DoUniform1iv(real_location, count, temp.get()); 5777 } else { 5778 glUniform1fv(real_location, count, value); 5779 } 5780 } 5781 5782 void GLES2DecoderImpl::DoUniform2fv( 5783 GLint fake_location, GLsizei count, const GLfloat* value) { 5784 GLenum type = 0; 5785 GLint real_location = -1; 5786 if (!PrepForSetUniformByLocation(fake_location, 5787 "glUniform2fv", 5788 Program::kUniform2f, 5789 &real_location, 5790 &type, 5791 &count)) { 5792 return; 5793 } 5794 if (type == GL_BOOL_VEC2) { 5795 GLsizei num_values = count * 2; 5796 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5797 for (GLsizei ii = 0; ii < num_values; ++ii) { 5798 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5799 } 5800 glUniform2iv(real_location, count, temp.get()); 5801 } else { 5802 glUniform2fv(real_location, count, value); 5803 } 5804 } 5805 5806 void GLES2DecoderImpl::DoUniform3fv( 5807 GLint fake_location, GLsizei count, const GLfloat* value) { 5808 GLenum type = 0; 5809 GLint real_location = -1; 5810 if (!PrepForSetUniformByLocation(fake_location, 5811 "glUniform3fv", 5812 Program::kUniform3f, 5813 &real_location, 5814 &type, 5815 &count)) { 5816 return; 5817 } 5818 if (type == GL_BOOL_VEC3) { 5819 GLsizei num_values = count * 3; 5820 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5821 for (GLsizei ii = 0; ii < num_values; ++ii) { 5822 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5823 } 5824 glUniform3iv(real_location, count, temp.get()); 5825 } else { 5826 glUniform3fv(real_location, count, value); 5827 } 5828 } 5829 5830 void GLES2DecoderImpl::DoUniform4fv( 5831 GLint fake_location, GLsizei count, const GLfloat* value) { 5832 GLenum type = 0; 5833 GLint real_location = -1; 5834 if (!PrepForSetUniformByLocation(fake_location, 5835 "glUniform4fv", 5836 Program::kUniform4f, 5837 &real_location, 5838 &type, 5839 &count)) { 5840 return; 5841 } 5842 if (type == GL_BOOL_VEC4) { 5843 GLsizei num_values = count * 4; 5844 scoped_ptr<GLint[]> temp(new GLint[num_values]); 5845 for (GLsizei ii = 0; ii < num_values; ++ii) { 5846 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 5847 } 5848 glUniform4iv(real_location, count, temp.get()); 5849 } else { 5850 glUniform4fv(real_location, count, value); 5851 } 5852 } 5853 5854 void GLES2DecoderImpl::DoUniform2iv( 5855 GLint fake_location, GLsizei count, const GLint* value) { 5856 GLenum type = 0; 5857 GLint real_location = -1; 5858 if (!PrepForSetUniformByLocation(fake_location, 5859 "glUniform2iv", 5860 Program::kUniform2i, 5861 &real_location, 5862 &type, 5863 &count)) { 5864 return; 5865 } 5866 glUniform2iv(real_location, count, value); 5867 } 5868 5869 void GLES2DecoderImpl::DoUniform3iv( 5870 GLint fake_location, GLsizei count, const GLint* value) { 5871 GLenum type = 0; 5872 GLint real_location = -1; 5873 if (!PrepForSetUniformByLocation(fake_location, 5874 "glUniform3iv", 5875 Program::kUniform3i, 5876 &real_location, 5877 &type, 5878 &count)) { 5879 return; 5880 } 5881 glUniform3iv(real_location, count, value); 5882 } 5883 5884 void GLES2DecoderImpl::DoUniform4iv( 5885 GLint fake_location, GLsizei count, const GLint* value) { 5886 GLenum type = 0; 5887 GLint real_location = -1; 5888 if (!PrepForSetUniformByLocation(fake_location, 5889 "glUniform4iv", 5890 Program::kUniform4i, 5891 &real_location, 5892 &type, 5893 &count)) { 5894 return; 5895 } 5896 glUniform4iv(real_location, count, value); 5897 } 5898 5899 void GLES2DecoderImpl::DoUniformMatrix2fv( 5900 GLint fake_location, GLsizei count, GLboolean transpose, 5901 const GLfloat* value) { 5902 GLenum type = 0; 5903 GLint real_location = -1; 5904 if (!PrepForSetUniformByLocation(fake_location, 5905 "glUniformMatrix2fv", 5906 Program::kUniformMatrix2f, 5907 &real_location, 5908 &type, 5909 &count)) { 5910 return; 5911 } 5912 glUniformMatrix2fv(real_location, count, transpose, value); 5913 } 5914 5915 void GLES2DecoderImpl::DoUniformMatrix3fv( 5916 GLint fake_location, GLsizei count, GLboolean transpose, 5917 const GLfloat* value) { 5918 GLenum type = 0; 5919 GLint real_location = -1; 5920 if (!PrepForSetUniformByLocation(fake_location, 5921 "glUniformMatrix3fv", 5922 Program::kUniformMatrix3f, 5923 &real_location, 5924 &type, 5925 &count)) { 5926 return; 5927 } 5928 glUniformMatrix3fv(real_location, count, transpose, value); 5929 } 5930 5931 void GLES2DecoderImpl::DoUniformMatrix4fv( 5932 GLint fake_location, GLsizei count, GLboolean transpose, 5933 const GLfloat* value) { 5934 GLenum type = 0; 5935 GLint real_location = -1; 5936 if (!PrepForSetUniformByLocation(fake_location, 5937 "glUniformMatrix4fv", 5938 Program::kUniformMatrix4f, 5939 &real_location, 5940 &type, 5941 &count)) { 5942 return; 5943 } 5944 glUniformMatrix4fv(real_location, count, transpose, value); 5945 } 5946 5947 void GLES2DecoderImpl::DoUseProgram(GLuint program_id) { 5948 GLuint service_id = 0; 5949 Program* program = NULL; 5950 if (program_id) { 5951 program = GetProgramInfoNotShader(program_id, "glUseProgram"); 5952 if (!program) { 5953 return; 5954 } 5955 if (!program->IsValid()) { 5956 // Program was not linked successfully. (ie, glLinkProgram) 5957 LOCAL_SET_GL_ERROR( 5958 GL_INVALID_OPERATION, "glUseProgram", "program not linked"); 5959 return; 5960 } 5961 service_id = program->service_id(); 5962 } 5963 if (state_.current_program.get()) { 5964 program_manager()->UnuseProgram(shader_manager(), 5965 state_.current_program.get()); 5966 } 5967 state_.current_program = program; 5968 LogClientServiceMapping("glUseProgram", program_id, service_id); 5969 glUseProgram(service_id); 5970 if (state_.current_program.get()) { 5971 program_manager()->UseProgram(state_.current_program.get()); 5972 if (workarounds().clear_uniforms_before_first_program_use) 5973 program_manager()->ClearUniforms(program); 5974 } 5975 } 5976 5977 void GLES2DecoderImpl::RenderWarning( 5978 const char* filename, int line, const std::string& msg) { 5979 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg); 5980 } 5981 5982 void GLES2DecoderImpl::PerformanceWarning( 5983 const char* filename, int line, const std::string& msg) { 5984 logger_.LogMessage(filename, line, 5985 std::string("PERFORMANCE WARNING: ") + msg); 5986 } 5987 5988 void GLES2DecoderImpl::DoWillUseTexImageIfNeeded( 5989 Texture* texture, GLenum textarget) { 5990 // Image is already in use if texture is attached to a framebuffer. 5991 if (texture && !texture->IsAttachedToFramebuffer()) { 5992 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 5993 if (image) { 5994 ScopedGLErrorSuppressor suppressor( 5995 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded", 5996 GetErrorState()); 5997 glBindTexture(textarget, texture->service_id()); 5998 image->WillUseTexImage(); 5999 RestoreCurrentTextureBindings(&state_, textarget); 6000 } 6001 } 6002 } 6003 6004 void GLES2DecoderImpl::DoDidUseTexImageIfNeeded( 6005 Texture* texture, GLenum textarget) { 6006 // Image is still in use if texture is attached to a framebuffer. 6007 if (texture && !texture->IsAttachedToFramebuffer()) { 6008 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 6009 if (image) { 6010 ScopedGLErrorSuppressor suppressor( 6011 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded", 6012 GetErrorState()); 6013 glBindTexture(textarget, texture->service_id()); 6014 image->DidUseTexImage(); 6015 RestoreCurrentTextureBindings(&state_, textarget); 6016 } 6017 } 6018 } 6019 6020 bool GLES2DecoderImpl::PrepareTexturesForRender() { 6021 DCHECK(state_.current_program.get()); 6022 if (!texture_manager()->HaveUnrenderableTextures() && 6023 !texture_manager()->HaveImages()) { 6024 return true; 6025 } 6026 6027 bool textures_set = false; 6028 const Program::SamplerIndices& sampler_indices = 6029 state_.current_program->sampler_indices(); 6030 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 6031 const Program::UniformInfo* uniform_info = 6032 state_.current_program->GetUniformInfo(sampler_indices[ii]); 6033 DCHECK(uniform_info); 6034 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 6035 GLuint texture_unit_index = uniform_info->texture_units[jj]; 6036 if (texture_unit_index < state_.texture_units.size()) { 6037 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 6038 TextureRef* texture_ref = 6039 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 6040 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type); 6041 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { 6042 textures_set = true; 6043 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6044 glBindTexture( 6045 textarget, 6046 texture_manager()->black_texture_id(uniform_info->type)); 6047 LOCAL_RENDER_WARNING( 6048 std::string("texture bound to texture unit ") + 6049 base::IntToString(texture_unit_index) + 6050 " is not renderable. It maybe non-power-of-2 and have" 6051 " incompatible texture filtering or is not" 6052 " 'texture complete'"); 6053 continue; 6054 } 6055 6056 if (textarget != GL_TEXTURE_CUBE_MAP) { 6057 Texture* texture = texture_ref->texture(); 6058 gfx::GLImage* image = texture->GetLevelImage(textarget, 0); 6059 if (image && !texture->IsAttachedToFramebuffer()) { 6060 ScopedGLErrorSuppressor suppressor( 6061 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState()); 6062 textures_set = true; 6063 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6064 image->WillUseTexImage(); 6065 continue; 6066 } 6067 } 6068 } 6069 // else: should this be an error? 6070 } 6071 } 6072 return !textures_set; 6073 } 6074 6075 void GLES2DecoderImpl::RestoreStateForTextures() { 6076 DCHECK(state_.current_program.get()); 6077 const Program::SamplerIndices& sampler_indices = 6078 state_.current_program->sampler_indices(); 6079 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 6080 const Program::UniformInfo* uniform_info = 6081 state_.current_program->GetUniformInfo(sampler_indices[ii]); 6082 DCHECK(uniform_info); 6083 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 6084 GLuint texture_unit_index = uniform_info->texture_units[jj]; 6085 if (texture_unit_index < state_.texture_units.size()) { 6086 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 6087 TextureRef* texture_ref = 6088 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 6089 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) { 6090 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6091 // Get the texture_ref info that was previously bound here. 6092 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D 6093 ? texture_unit.bound_texture_2d.get() 6094 : texture_unit.bound_texture_cube_map.get(); 6095 glBindTexture(texture_unit.bind_target, 6096 texture_ref ? texture_ref->service_id() : 0); 6097 continue; 6098 } 6099 6100 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) { 6101 Texture* texture = texture_ref->texture(); 6102 gfx::GLImage* image = 6103 texture->GetLevelImage(texture_unit.bind_target, 0); 6104 if (image && !texture->IsAttachedToFramebuffer()) { 6105 ScopedGLErrorSuppressor suppressor( 6106 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState()); 6107 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 6108 image->DidUseTexImage(); 6109 continue; 6110 } 6111 } 6112 } 6113 } 6114 } 6115 // Set the active texture back to whatever the user had it as. 6116 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 6117 } 6118 6119 bool GLES2DecoderImpl::ClearUnclearedTextures() { 6120 // Only check if there are some uncleared textures. 6121 if (!texture_manager()->HaveUnsafeTextures()) { 6122 return true; 6123 } 6124 6125 // 1: Check all textures we are about to render with. 6126 if (state_.current_program.get()) { 6127 const Program::SamplerIndices& sampler_indices = 6128 state_.current_program->sampler_indices(); 6129 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 6130 const Program::UniformInfo* uniform_info = 6131 state_.current_program->GetUniformInfo(sampler_indices[ii]); 6132 DCHECK(uniform_info); 6133 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 6134 GLuint texture_unit_index = uniform_info->texture_units[jj]; 6135 if (texture_unit_index < state_.texture_units.size()) { 6136 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 6137 TextureRef* texture_ref = 6138 texture_unit.GetInfoForSamplerType(uniform_info->type).get(); 6139 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) { 6140 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) { 6141 return false; 6142 } 6143 } 6144 } 6145 } 6146 } 6147 } 6148 return true; 6149 } 6150 6151 bool GLES2DecoderImpl::IsDrawValid( 6152 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) { 6153 // NOTE: We specifically do not check current_program->IsValid() because 6154 // it could never be invalid since glUseProgram would have failed. While 6155 // glLinkProgram could later mark the program as invalid the previous 6156 // valid program will still function if it is still the current program. 6157 if (!state_.current_program.get()) { 6158 // The program does not exist. 6159 // But GL says no ERROR. 6160 LOCAL_RENDER_WARNING("Drawing with no current shader program."); 6161 return false; 6162 } 6163 6164 return state_.vertex_attrib_manager 6165 ->ValidateBindings(function_name, 6166 this, 6167 feature_info_.get(), 6168 state_.current_program.get(), 6169 max_vertex_accessed, 6170 primcount); 6171 } 6172 6173 bool GLES2DecoderImpl::SimulateAttrib0( 6174 const char* function_name, GLuint max_vertex_accessed, bool* simulated) { 6175 DCHECK(simulated); 6176 *simulated = false; 6177 6178 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 6179 return true; 6180 6181 const VertexAttrib* attrib = 6182 state_.vertex_attrib_manager->GetVertexAttrib(0); 6183 // If it's enabled or it's not used then we don't need to do anything. 6184 bool attrib_0_used = 6185 state_.current_program->GetAttribInfoByLocation(0) != NULL; 6186 if (attrib->enabled() && attrib_0_used) { 6187 return true; 6188 } 6189 6190 // Make a buffer with a single repeated vec4 value enough to 6191 // simulate the constant value that is supposed to be here. 6192 // This is required to emulate GLES2 on GL. 6193 GLuint num_vertices = max_vertex_accessed + 1; 6194 uint32 size_needed = 0; 6195 6196 if (num_vertices == 0 || 6197 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) || 6198 size_needed > 0x7FFFFFFFU) { 6199 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6200 return false; 6201 } 6202 6203 LOCAL_PERFORMANCE_WARNING( 6204 "Attribute 0 is disabled. This has signficant performance penalty"); 6205 6206 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 6207 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 6208 6209 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_; 6210 if (new_buffer) { 6211 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 6212 GLenum error = glGetError(); 6213 if (error != GL_NO_ERROR) { 6214 LOCAL_SET_GL_ERROR( 6215 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6216 return false; 6217 } 6218 } 6219 6220 const Vec4& value = state_.attrib_values[0]; 6221 if (new_buffer || 6222 (attrib_0_used && 6223 (!attrib_0_buffer_matches_value_ || 6224 (value.v[0] != attrib_0_value_.v[0] || 6225 value.v[1] != attrib_0_value_.v[1] || 6226 value.v[2] != attrib_0_value_.v[2] || 6227 value.v[3] != attrib_0_value_.v[3])))) { 6228 std::vector<Vec4> temp(num_vertices, value); 6229 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); 6230 attrib_0_buffer_matches_value_ = true; 6231 attrib_0_value_ = value; 6232 attrib_0_size_ = size_needed; 6233 } 6234 6235 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); 6236 6237 if (attrib->divisor()) 6238 glVertexAttribDivisorANGLE(0, 0); 6239 6240 *simulated = true; 6241 return true; 6242 } 6243 6244 void GLES2DecoderImpl::RestoreStateForAttrib( 6245 GLuint attrib_index, bool restore_array_binding) { 6246 const VertexAttrib* attrib = 6247 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index); 6248 if (restore_array_binding) { 6249 const void* ptr = reinterpret_cast<const void*>(attrib->offset()); 6250 Buffer* buffer = attrib->buffer(); 6251 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0); 6252 glVertexAttribPointer( 6253 attrib_index, attrib->size(), attrib->type(), attrib->normalized(), 6254 attrib->gl_stride(), ptr); 6255 } 6256 if (attrib->divisor()) 6257 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor()); 6258 glBindBuffer( 6259 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ? 6260 state_.bound_array_buffer->service_id() : 0); 6261 6262 // Never touch vertex attribute 0's state (in particular, never 6263 // disable it) when running on desktop GL because it will never be 6264 // re-enabled. 6265 if (attrib_index != 0 || 6266 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 6267 if (attrib->enabled()) { 6268 glEnableVertexAttribArray(attrib_index); 6269 } else { 6270 glDisableVertexAttribArray(attrib_index); 6271 } 6272 } 6273 } 6274 6275 bool GLES2DecoderImpl::SimulateFixedAttribs( 6276 const char* function_name, 6277 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) { 6278 DCHECK(simulated); 6279 *simulated = false; 6280 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 6281 return true; 6282 6283 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) { 6284 return true; 6285 } 6286 6287 LOCAL_PERFORMANCE_WARNING( 6288 "GL_FIXED attributes have a signficant performance penalty"); 6289 6290 // NOTE: we could be smart and try to check if a buffer is used 6291 // twice in 2 different attribs, find the overlapping parts and therefore 6292 // duplicate the minimum amount of data but this whole code path is not meant 6293 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance 6294 // tests so we just add to the buffer attrib used. 6295 6296 GLuint elements_needed = 0; 6297 const VertexAttribManager::VertexAttribList& enabled_attribs = 6298 state_.vertex_attrib_manager->GetEnabledVertexAttribs(); 6299 for (VertexAttribManager::VertexAttribList::const_iterator it = 6300 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) { 6301 const VertexAttrib* attrib = *it; 6302 const Program::VertexAttrib* attrib_info = 6303 state_.current_program->GetAttribInfoByLocation(attrib->index()); 6304 GLuint max_accessed = attrib->MaxVertexAccessed(primcount, 6305 max_vertex_accessed); 6306 GLuint num_vertices = max_accessed + 1; 6307 if (num_vertices == 0) { 6308 LOCAL_SET_GL_ERROR( 6309 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6310 return false; 6311 } 6312 if (attrib_info && 6313 attrib->CanAccess(max_accessed) && 6314 attrib->type() == GL_FIXED) { 6315 uint32 elements_used = 0; 6316 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) || 6317 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) { 6318 LOCAL_SET_GL_ERROR( 6319 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6320 return false; 6321 } 6322 } 6323 } 6324 6325 const uint32 kSizeOfFloat = sizeof(float); // NOLINT 6326 uint32 size_needed = 0; 6327 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) || 6328 size_needed > 0x7FFFFFFFU) { 6329 LOCAL_SET_GL_ERROR( 6330 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6331 return false; 6332 } 6333 6334 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name); 6335 6336 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); 6337 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) { 6338 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 6339 GLenum error = glGetError(); 6340 if (error != GL_NO_ERROR) { 6341 LOCAL_SET_GL_ERROR( 6342 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 6343 return false; 6344 } 6345 } 6346 6347 // Copy the elements and convert to float 6348 GLintptr offset = 0; 6349 for (VertexAttribManager::VertexAttribList::const_iterator it = 6350 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) { 6351 const VertexAttrib* attrib = *it; 6352 const Program::VertexAttrib* attrib_info = 6353 state_.current_program->GetAttribInfoByLocation(attrib->index()); 6354 GLuint max_accessed = attrib->MaxVertexAccessed(primcount, 6355 max_vertex_accessed); 6356 GLuint num_vertices = max_accessed + 1; 6357 if (num_vertices == 0) { 6358 LOCAL_SET_GL_ERROR( 6359 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 6360 return false; 6361 } 6362 if (attrib_info && 6363 attrib->CanAccess(max_accessed) && 6364 attrib->type() == GL_FIXED) { 6365 int num_elements = attrib->size() * kSizeOfFloat; 6366 int size = num_elements * num_vertices; 6367 scoped_ptr<float[]> data(new float[size]); 6368 const int32* src = reinterpret_cast<const int32 *>( 6369 attrib->buffer()->GetRange(attrib->offset(), size)); 6370 const int32* end = src + num_elements; 6371 float* dst = data.get(); 6372 while (src != end) { 6373 *dst++ = static_cast<float>(*src++) / 65536.0f; 6374 } 6375 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get()); 6376 glVertexAttribPointer( 6377 attrib->index(), attrib->size(), GL_FLOAT, false, 0, 6378 reinterpret_cast<GLvoid*>(offset)); 6379 offset += size; 6380 } 6381 } 6382 *simulated = true; 6383 return true; 6384 } 6385 6386 void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() { 6387 // There's no need to call glVertexAttribPointer because we shadow all the 6388 // settings and passing GL_FIXED to it will not work. 6389 glBindBuffer( 6390 GL_ARRAY_BUFFER, 6391 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id() 6392 : 0); 6393 } 6394 6395 error::Error GLES2DecoderImpl::DoDrawArrays( 6396 const char* function_name, 6397 bool instanced, 6398 GLenum mode, 6399 GLint first, 6400 GLsizei count, 6401 GLsizei primcount) { 6402 error::Error error = WillAccessBoundFramebufferForDraw(); 6403 if (error != error::kNoError) 6404 return error; 6405 if (!validators_->draw_mode.IsValid(mode)) { 6406 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); 6407 return error::kNoError; 6408 } 6409 if (count < 0) { 6410 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0"); 6411 return error::kNoError; 6412 } 6413 if (primcount < 0) { 6414 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); 6415 return error::kNoError; 6416 } 6417 if (!CheckBoundFramebuffersValid(function_name)) { 6418 return error::kNoError; 6419 } 6420 // We have to check this here because the prototype for glDrawArrays 6421 // is GLint not GLsizei. 6422 if (first < 0) { 6423 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0"); 6424 return error::kNoError; 6425 } 6426 6427 if (count == 0 || (instanced && primcount == 0)) { 6428 LOCAL_RENDER_WARNING("Render count or primcount is 0."); 6429 return error::kNoError; 6430 } 6431 6432 GLuint max_vertex_accessed = first + count - 1; 6433 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { 6434 if (!ClearUnclearedTextures()) { 6435 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 6436 return error::kNoError; 6437 } 6438 bool simulated_attrib_0 = false; 6439 if (!SimulateAttrib0( 6440 function_name, max_vertex_accessed, &simulated_attrib_0)) { 6441 return error::kNoError; 6442 } 6443 bool simulated_fixed_attribs = false; 6444 if (SimulateFixedAttribs( 6445 function_name, max_vertex_accessed, &simulated_fixed_attribs, 6446 primcount)) { 6447 bool textures_set = !PrepareTexturesForRender(); 6448 ApplyDirtyState(); 6449 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 6450 if (!instanced) { 6451 glDrawArrays(mode, first, count); 6452 } else { 6453 glDrawArraysInstancedANGLE(mode, first, count, primcount); 6454 } 6455 if (textures_set) { 6456 RestoreStateForTextures(); 6457 } 6458 if (simulated_fixed_attribs) { 6459 RestoreStateForSimulatedFixedAttribs(); 6460 } 6461 } 6462 if (simulated_attrib_0) { 6463 // We don't have to restore attrib 0 generic data at the end of this 6464 // function even if it is simulated. This is because we will simulate 6465 // it in each draw call, and attrib 0 generic data queries use cached 6466 // values instead of passing down to the underlying driver. 6467 RestoreStateForAttrib(0, false); 6468 } 6469 } 6470 return error::kNoError; 6471 } 6472 6473 error::Error GLES2DecoderImpl::HandleDrawArrays( 6474 uint32 immediate_data_size, const cmds::DrawArrays& c) { 6475 return DoDrawArrays("glDrawArrays", 6476 false, 6477 static_cast<GLenum>(c.mode), 6478 static_cast<GLint>(c.first), 6479 static_cast<GLsizei>(c.count), 6480 0); 6481 } 6482 6483 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE( 6484 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) { 6485 if (!features().angle_instanced_arrays) { 6486 LOCAL_SET_GL_ERROR( 6487 GL_INVALID_OPERATION, 6488 "glDrawArraysInstancedANGLE", "function not available"); 6489 return error::kNoError; 6490 } 6491 return DoDrawArrays("glDrawArraysIntancedANGLE", 6492 true, 6493 static_cast<GLenum>(c.mode), 6494 static_cast<GLint>(c.first), 6495 static_cast<GLsizei>(c.count), 6496 static_cast<GLsizei>(c.primcount)); 6497 } 6498 6499 error::Error GLES2DecoderImpl::DoDrawElements( 6500 const char* function_name, 6501 bool instanced, 6502 GLenum mode, 6503 GLsizei count, 6504 GLenum type, 6505 int32 offset, 6506 GLsizei primcount) { 6507 error::Error error = WillAccessBoundFramebufferForDraw(); 6508 if (error != error::kNoError) 6509 return error; 6510 if (!state_.vertex_attrib_manager->element_array_buffer()) { 6511 LOCAL_SET_GL_ERROR( 6512 GL_INVALID_OPERATION, function_name, "No element array buffer bound"); 6513 return error::kNoError; 6514 } 6515 6516 if (count < 0) { 6517 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0"); 6518 return error::kNoError; 6519 } 6520 if (offset < 0) { 6521 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0"); 6522 return error::kNoError; 6523 } 6524 if (!validators_->draw_mode.IsValid(mode)) { 6525 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode"); 6526 return error::kNoError; 6527 } 6528 if (!validators_->index_type.IsValid(type)) { 6529 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type"); 6530 return error::kNoError; 6531 } 6532 if (primcount < 0) { 6533 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0"); 6534 return error::kNoError; 6535 } 6536 6537 if (!CheckBoundFramebuffersValid(function_name)) { 6538 return error::kNoError; 6539 } 6540 6541 if (count == 0 || (instanced && primcount == 0)) { 6542 return error::kNoError; 6543 } 6544 6545 GLuint max_vertex_accessed; 6546 Buffer* element_array_buffer = 6547 state_.vertex_attrib_manager->element_array_buffer(); 6548 6549 if (!element_array_buffer->GetMaxValueForRange( 6550 offset, count, type, &max_vertex_accessed)) { 6551 LOCAL_SET_GL_ERROR( 6552 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); 6553 return error::kNoError; 6554 } 6555 6556 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { 6557 if (!ClearUnclearedTextures()) { 6558 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); 6559 return error::kNoError; 6560 } 6561 bool simulated_attrib_0 = false; 6562 if (!SimulateAttrib0( 6563 function_name, max_vertex_accessed, &simulated_attrib_0)) { 6564 return error::kNoError; 6565 } 6566 bool simulated_fixed_attribs = false; 6567 if (SimulateFixedAttribs( 6568 function_name, max_vertex_accessed, &simulated_fixed_attribs, 6569 primcount)) { 6570 bool textures_set = !PrepareTexturesForRender(); 6571 ApplyDirtyState(); 6572 // TODO(gman): Refactor to hide these details in BufferManager or 6573 // VertexAttribManager. 6574 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 6575 bool used_client_side_array = false; 6576 if (element_array_buffer->IsClientSideArray()) { 6577 used_client_side_array = true; 6578 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 6579 indices = element_array_buffer->GetRange(offset, 0); 6580 } 6581 6582 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); 6583 if (!instanced) { 6584 glDrawElements(mode, count, type, indices); 6585 } else { 6586 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); 6587 } 6588 6589 if (used_client_side_array) { 6590 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 6591 element_array_buffer->service_id()); 6592 } 6593 6594 if (textures_set) { 6595 RestoreStateForTextures(); 6596 } 6597 if (simulated_fixed_attribs) { 6598 RestoreStateForSimulatedFixedAttribs(); 6599 } 6600 } 6601 if (simulated_attrib_0) { 6602 // We don't have to restore attrib 0 generic data at the end of this 6603 // function even if it is simulated. This is because we will simulate 6604 // it in each draw call, and attrib 0 generic data queries use cached 6605 // values instead of passing down to the underlying driver. 6606 RestoreStateForAttrib(0, false); 6607 } 6608 } 6609 return error::kNoError; 6610 } 6611 6612 error::Error GLES2DecoderImpl::HandleDrawElements( 6613 uint32 immediate_data_size, const cmds::DrawElements& c) { 6614 return DoDrawElements("glDrawElements", 6615 false, 6616 static_cast<GLenum>(c.mode), 6617 static_cast<GLsizei>(c.count), 6618 static_cast<GLenum>(c.type), 6619 static_cast<int32>(c.index_offset), 6620 0); 6621 } 6622 6623 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE( 6624 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) { 6625 if (!features().angle_instanced_arrays) { 6626 LOCAL_SET_GL_ERROR( 6627 GL_INVALID_OPERATION, 6628 "glDrawElementsInstancedANGLE", "function not available"); 6629 return error::kNoError; 6630 } 6631 return DoDrawElements("glDrawElementsInstancedANGLE", 6632 true, 6633 static_cast<GLenum>(c.mode), 6634 static_cast<GLsizei>(c.count), 6635 static_cast<GLenum>(c.type), 6636 static_cast<int32>(c.index_offset), 6637 static_cast<GLsizei>(c.primcount)); 6638 } 6639 6640 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( 6641 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { 6642 GLuint max_vertex_accessed = 0; 6643 Buffer* buffer = GetBuffer(buffer_id); 6644 if (!buffer) { 6645 // TODO(gman): Should this be a GL error or a command buffer error? 6646 LOCAL_SET_GL_ERROR( 6647 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer"); 6648 } else { 6649 if (!buffer->GetMaxValueForRange( 6650 offset, count, type, &max_vertex_accessed)) { 6651 // TODO(gman): Should this be a GL error or a command buffer error? 6652 LOCAL_SET_GL_ERROR( 6653 GL_INVALID_OPERATION, 6654 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer"); 6655 } 6656 } 6657 return max_vertex_accessed; 6658 } 6659 6660 // Calls glShaderSource for the various versions of the ShaderSource command. 6661 // Assumes that data / data_size points to a piece of memory that is in range 6662 // of whatever context it came from (shared memory, immediate memory, bucket 6663 // memory.) 6664 error::Error GLES2DecoderImpl::ShaderSourceHelper( 6665 GLuint client_id, const char* data, uint32 data_size) { 6666 std::string str(data, data + data_size); 6667 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource"); 6668 if (!shader) { 6669 return error::kNoError; 6670 } 6671 // Note: We don't actually call glShaderSource here. We wait until 6672 // the call to glCompileShader. 6673 shader->UpdateSource(str.c_str()); 6674 return error::kNoError; 6675 } 6676 6677 error::Error GLES2DecoderImpl::HandleShaderSourceBucket( 6678 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) { 6679 Bucket* bucket = GetBucket(c.data_bucket_id); 6680 if (!bucket || bucket->size() == 0) { 6681 return error::kInvalidArguments; 6682 } 6683 return ShaderSourceHelper( 6684 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1), 6685 bucket->size() - 1); 6686 } 6687 6688 void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { 6689 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader"); 6690 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader"); 6691 if (!shader) { 6692 return; 6693 } 6694 ShaderTranslator* translator = NULL; 6695 if (use_shader_translator_) { 6696 translator = shader->shader_type() == GL_VERTEX_SHADER ? 6697 vertex_translator_.get() : fragment_translator_.get(); 6698 } 6699 6700 program_manager()->DoCompileShader( 6701 shader, 6702 translator, 6703 feature_info_->feature_flags().angle_translated_shader_source ? 6704 ProgramManager::kANGLE : ProgramManager::kGL); 6705 }; 6706 6707 void GLES2DecoderImpl::DoGetShaderiv( 6708 GLuint shader_id, GLenum pname, GLint* params) { 6709 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv"); 6710 if (!shader) { 6711 return; 6712 } 6713 switch (pname) { 6714 case GL_SHADER_SOURCE_LENGTH: 6715 *params = shader->source() ? shader->source()->size() + 1 : 0; 6716 return; 6717 case GL_COMPILE_STATUS: 6718 *params = compile_shader_always_succeeds_ ? true : shader->IsValid(); 6719 return; 6720 case GL_INFO_LOG_LENGTH: 6721 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0; 6722 return; 6723 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 6724 *params = shader->translated_source() ? 6725 shader->translated_source()->size() + 1 : 0; 6726 return; 6727 default: 6728 break; 6729 } 6730 glGetShaderiv(shader->service_id(), pname, params); 6731 } 6732 6733 error::Error GLES2DecoderImpl::HandleGetShaderSource( 6734 uint32 immediate_data_size, const cmds::GetShaderSource& c) { 6735 GLuint shader_id = c.shader; 6736 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6737 Bucket* bucket = CreateBucket(bucket_id); 6738 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource"); 6739 if (!shader || !shader->source()) { 6740 bucket->SetSize(0); 6741 return error::kNoError; 6742 } 6743 bucket->SetFromString(shader->source()->c_str()); 6744 return error::kNoError; 6745 } 6746 6747 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( 6748 uint32 immediate_data_size, 6749 const cmds::GetTranslatedShaderSourceANGLE& c) { 6750 GLuint shader_id = c.shader; 6751 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6752 Bucket* bucket = CreateBucket(bucket_id); 6753 Shader* shader = GetShaderInfoNotProgram( 6754 shader_id, "glGetTranslatedShaderSourceANGLE"); 6755 if (!shader) { 6756 bucket->SetSize(0); 6757 return error::kNoError; 6758 } 6759 6760 bucket->SetFromString(shader->translated_source() ? 6761 shader->translated_source()->c_str() : NULL); 6762 return error::kNoError; 6763 } 6764 6765 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog( 6766 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) { 6767 GLuint program_id = c.program; 6768 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6769 Bucket* bucket = CreateBucket(bucket_id); 6770 Program* program = GetProgramInfoNotShader( 6771 program_id, "glGetProgramInfoLog"); 6772 if (!program || !program->log_info()) { 6773 bucket->SetFromString(""); 6774 return error::kNoError; 6775 } 6776 bucket->SetFromString(program->log_info()->c_str()); 6777 return error::kNoError; 6778 } 6779 6780 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( 6781 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) { 6782 GLuint shader_id = c.shader; 6783 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 6784 Bucket* bucket = CreateBucket(bucket_id); 6785 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog"); 6786 if (!shader || !shader->log_info()) { 6787 bucket->SetFromString(""); 6788 return error::kNoError; 6789 } 6790 bucket->SetFromString(shader->log_info()->c_str()); 6791 return error::kNoError; 6792 } 6793 6794 bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) { 6795 return state_.GetEnabled(cap); 6796 } 6797 6798 bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) { 6799 const Buffer* buffer = GetBuffer(client_id); 6800 return buffer && buffer->IsValid() && !buffer->IsDeleted(); 6801 } 6802 6803 bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) { 6804 const Framebuffer* framebuffer = 6805 GetFramebuffer(client_id); 6806 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted(); 6807 } 6808 6809 bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) { 6810 // IsProgram is true for programs as soon as they are created, until they are 6811 // deleted and no longer in use. 6812 const Program* program = GetProgram(client_id); 6813 return program != NULL && !program->IsDeleted(); 6814 } 6815 6816 bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) { 6817 const Renderbuffer* renderbuffer = 6818 GetRenderbuffer(client_id); 6819 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted(); 6820 } 6821 6822 bool GLES2DecoderImpl::DoIsShader(GLuint client_id) { 6823 // IsShader is true for shaders as soon as they are created, until they 6824 // are deleted and not attached to any programs. 6825 const Shader* shader = GetShader(client_id); 6826 return shader != NULL && !shader->IsDeleted(); 6827 } 6828 6829 bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) { 6830 const TextureRef* texture_ref = GetTexture(client_id); 6831 return texture_ref && texture_ref->texture()->IsValid(); 6832 } 6833 6834 void GLES2DecoderImpl::DoAttachShader( 6835 GLuint program_client_id, GLint shader_client_id) { 6836 Program* program = GetProgramInfoNotShader( 6837 program_client_id, "glAttachShader"); 6838 if (!program) { 6839 return; 6840 } 6841 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader"); 6842 if (!shader) { 6843 return; 6844 } 6845 if (!program->AttachShader(shader_manager(), shader)) { 6846 LOCAL_SET_GL_ERROR( 6847 GL_INVALID_OPERATION, 6848 "glAttachShader", 6849 "can not attach more than one shader of the same type."); 6850 return; 6851 } 6852 glAttachShader(program->service_id(), shader->service_id()); 6853 } 6854 6855 void GLES2DecoderImpl::DoDetachShader( 6856 GLuint program_client_id, GLint shader_client_id) { 6857 Program* program = GetProgramInfoNotShader( 6858 program_client_id, "glDetachShader"); 6859 if (!program) { 6860 return; 6861 } 6862 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader"); 6863 if (!shader) { 6864 return; 6865 } 6866 if (!program->DetachShader(shader_manager(), shader)) { 6867 LOCAL_SET_GL_ERROR( 6868 GL_INVALID_OPERATION, 6869 "glDetachShader", "shader not attached to program"); 6870 return; 6871 } 6872 glDetachShader(program->service_id(), shader->service_id()); 6873 } 6874 6875 void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) { 6876 Program* program = GetProgramInfoNotShader( 6877 program_client_id, "glValidateProgram"); 6878 if (!program) { 6879 return; 6880 } 6881 program->Validate(); 6882 } 6883 6884 void GLES2DecoderImpl::GetVertexAttribHelper( 6885 const VertexAttrib* attrib, GLenum pname, GLint* params) { 6886 switch (pname) { 6887 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { 6888 Buffer* buffer = attrib->buffer(); 6889 if (buffer && !buffer->IsDeleted()) { 6890 GLuint client_id; 6891 buffer_manager()->GetClientId(buffer->service_id(), &client_id); 6892 *params = client_id; 6893 } 6894 break; 6895 } 6896 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 6897 *params = attrib->enabled(); 6898 break; 6899 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 6900 *params = attrib->size(); 6901 break; 6902 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 6903 *params = attrib->gl_stride(); 6904 break; 6905 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 6906 *params = attrib->type(); 6907 break; 6908 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 6909 *params = attrib->normalized(); 6910 break; 6911 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 6912 *params = attrib->divisor(); 6913 break; 6914 default: 6915 NOTREACHED(); 6916 break; 6917 } 6918 } 6919 6920 void GLES2DecoderImpl::DoGetTexParameterfv( 6921 GLenum target, GLenum pname, GLfloat* params) { 6922 InitTextureMaxAnisotropyIfNeeded(target, pname); 6923 glGetTexParameterfv(target, pname, params); 6924 } 6925 6926 void GLES2DecoderImpl::DoGetTexParameteriv( 6927 GLenum target, GLenum pname, GLint* params) { 6928 InitTextureMaxAnisotropyIfNeeded(target, pname); 6929 glGetTexParameteriv(target, pname, params); 6930 } 6931 6932 void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded( 6933 GLenum target, GLenum pname) { 6934 if (!workarounds().init_texture_max_anisotropy) 6935 return; 6936 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT || 6937 !validators_->texture_parameter.IsValid(pname)) { 6938 return; 6939 } 6940 6941 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( 6942 &state_, target); 6943 if (!texture_ref) { 6944 LOCAL_SET_GL_ERROR( 6945 GL_INVALID_OPERATION, 6946 "glGetTexParamter{fi}v", "unknown texture for target"); 6947 return; 6948 } 6949 Texture* texture = texture_ref->texture(); 6950 texture->InitTextureMaxAnisotropyIfNeeded(target); 6951 } 6952 6953 void GLES2DecoderImpl::DoGetVertexAttribfv( 6954 GLuint index, GLenum pname, GLfloat* params) { 6955 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); 6956 if (!attrib) { 6957 LOCAL_SET_GL_ERROR( 6958 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range"); 6959 return; 6960 } 6961 switch (pname) { 6962 case GL_CURRENT_VERTEX_ATTRIB: { 6963 const Vec4& value = state_.attrib_values[index]; 6964 params[0] = value.v[0]; 6965 params[1] = value.v[1]; 6966 params[2] = value.v[2]; 6967 params[3] = value.v[3]; 6968 break; 6969 } 6970 default: { 6971 GLint value = 0; 6972 GetVertexAttribHelper(attrib, pname, &value); 6973 *params = static_cast<GLfloat>(value); 6974 break; 6975 } 6976 } 6977 } 6978 6979 void GLES2DecoderImpl::DoGetVertexAttribiv( 6980 GLuint index, GLenum pname, GLint* params) { 6981 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index); 6982 if (!attrib) { 6983 LOCAL_SET_GL_ERROR( 6984 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range"); 6985 return; 6986 } 6987 switch (pname) { 6988 case GL_CURRENT_VERTEX_ATTRIB: { 6989 const Vec4& value = state_.attrib_values[index]; 6990 params[0] = static_cast<GLint>(value.v[0]); 6991 params[1] = static_cast<GLint>(value.v[1]); 6992 params[2] = static_cast<GLint>(value.v[2]); 6993 params[3] = static_cast<GLint>(value.v[3]); 6994 break; 6995 } 6996 default: 6997 GetVertexAttribHelper(attrib, pname, params); 6998 break; 6999 } 7000 } 7001 7002 bool GLES2DecoderImpl::SetVertexAttribValue( 7003 const char* function_name, GLuint index, const GLfloat* value) { 7004 if (index >= state_.attrib_values.size()) { 7005 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range"); 7006 return false; 7007 } 7008 Vec4& v = state_.attrib_values[index]; 7009 v.v[0] = value[0]; 7010 v.v[1] = value[1]; 7011 v.v[2] = value[2]; 7012 v.v[3] = value[3]; 7013 return true; 7014 } 7015 7016 void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) { 7017 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, }; 7018 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) { 7019 glVertexAttrib1f(index, v0); 7020 } 7021 } 7022 7023 void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) { 7024 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, }; 7025 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) { 7026 glVertexAttrib2f(index, v0, v1); 7027 } 7028 } 7029 7030 void GLES2DecoderImpl::DoVertexAttrib3f( 7031 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) { 7032 GLfloat v[4] = { v0, v1, v2, 1.0f, }; 7033 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) { 7034 glVertexAttrib3f(index, v0, v1, v2); 7035 } 7036 } 7037 7038 void GLES2DecoderImpl::DoVertexAttrib4f( 7039 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { 7040 GLfloat v[4] = { v0, v1, v2, v3, }; 7041 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) { 7042 glVertexAttrib4f(index, v0, v1, v2, v3); 7043 } 7044 } 7045 7046 void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) { 7047 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, }; 7048 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) { 7049 glVertexAttrib1fv(index, v); 7050 } 7051 } 7052 7053 void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) { 7054 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, }; 7055 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) { 7056 glVertexAttrib2fv(index, v); 7057 } 7058 } 7059 7060 void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) { 7061 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, }; 7062 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) { 7063 glVertexAttrib3fv(index, v); 7064 } 7065 } 7066 7067 void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) { 7068 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) { 7069 glVertexAttrib4fv(index, v); 7070 } 7071 } 7072 7073 error::Error GLES2DecoderImpl::HandleVertexAttribPointer( 7074 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) { 7075 7076 if (!state_.bound_array_buffer.get() || 7077 state_.bound_array_buffer->IsDeleted()) { 7078 if (state_.vertex_attrib_manager.get() == 7079 state_.default_vertex_attrib_manager.get()) { 7080 LOCAL_SET_GL_ERROR( 7081 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound"); 7082 return error::kNoError; 7083 } else if (c.offset != 0) { 7084 LOCAL_SET_GL_ERROR( 7085 GL_INVALID_VALUE, 7086 "glVertexAttribPointer", "client side arrays are not allowed"); 7087 return error::kNoError; 7088 } 7089 } 7090 7091 GLuint indx = c.indx; 7092 GLint size = c.size; 7093 GLenum type = c.type; 7094 GLboolean normalized = c.normalized; 7095 GLsizei stride = c.stride; 7096 GLsizei offset = c.offset; 7097 const void* ptr = reinterpret_cast<const void*>(offset); 7098 if (!validators_->vertex_attrib_type.IsValid(type)) { 7099 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type"); 7100 return error::kNoError; 7101 } 7102 if (!validators_->vertex_attrib_size.IsValid(size)) { 7103 LOCAL_SET_GL_ERROR( 7104 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE"); 7105 return error::kNoError; 7106 } 7107 if (indx >= group_->max_vertex_attribs()) { 7108 LOCAL_SET_GL_ERROR( 7109 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range"); 7110 return error::kNoError; 7111 } 7112 if (stride < 0) { 7113 LOCAL_SET_GL_ERROR( 7114 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0"); 7115 return error::kNoError; 7116 } 7117 if (stride > 255) { 7118 LOCAL_SET_GL_ERROR( 7119 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255"); 7120 return error::kNoError; 7121 } 7122 if (offset < 0) { 7123 LOCAL_SET_GL_ERROR( 7124 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0"); 7125 return error::kNoError; 7126 } 7127 GLsizei component_size = 7128 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); 7129 if (offset % component_size > 0) { 7130 LOCAL_SET_GL_ERROR( 7131 GL_INVALID_OPERATION, 7132 "glVertexAttribPointer", "offset not valid for type"); 7133 return error::kNoError; 7134 } 7135 if (stride % component_size > 0) { 7136 LOCAL_SET_GL_ERROR( 7137 GL_INVALID_OPERATION, 7138 "glVertexAttribPointer", "stride not valid for type"); 7139 return error::kNoError; 7140 } 7141 state_.vertex_attrib_manager 7142 ->SetAttribInfo(indx, 7143 state_.bound_array_buffer.get(), 7144 size, 7145 type, 7146 normalized, 7147 stride, 7148 stride != 0 ? stride : component_size * size, 7149 offset); 7150 if (type != GL_FIXED) { 7151 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); 7152 } 7153 return error::kNoError; 7154 } 7155 7156 void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width, 7157 GLsizei height) { 7158 state_.viewport_x = x; 7159 state_.viewport_y = y; 7160 state_.viewport_width = std::min(width, viewport_max_width_); 7161 state_.viewport_height = std::min(height, viewport_max_height_); 7162 glViewport(x, y, width, height); 7163 } 7164 7165 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( 7166 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) { 7167 if (!features().angle_instanced_arrays) { 7168 LOCAL_SET_GL_ERROR( 7169 GL_INVALID_OPERATION, 7170 "glVertexAttribDivisorANGLE", "function not available"); 7171 return error::kNoError; 7172 } 7173 GLuint index = c.index; 7174 GLuint divisor = c.divisor; 7175 if (index >= group_->max_vertex_attribs()) { 7176 LOCAL_SET_GL_ERROR( 7177 GL_INVALID_VALUE, 7178 "glVertexAttribDivisorANGLE", "index out of range"); 7179 return error::kNoError; 7180 } 7181 7182 state_.vertex_attrib_manager->SetDivisor( 7183 index, 7184 divisor); 7185 glVertexAttribDivisorANGLE(index, divisor); 7186 return error::kNoError; 7187 } 7188 7189 template <typename pixel_data_type> 7190 static void WriteAlphaData( 7191 void *pixels, uint32 row_count, uint32 channel_count, 7192 uint32 alpha_channel_index, uint32 unpadded_row_size, 7193 uint32 padded_row_size, pixel_data_type alpha_value) { 7194 DCHECK_GT(channel_count, 0U); 7195 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U); 7196 uint32 unpadded_row_size_in_elements = 7197 unpadded_row_size / sizeof(pixel_data_type); 7198 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U); 7199 uint32 padded_row_size_in_elements = 7200 padded_row_size / sizeof(pixel_data_type); 7201 pixel_data_type* dst = 7202 static_cast<pixel_data_type*>(pixels) + alpha_channel_index; 7203 for (uint32 yy = 0; yy < row_count; ++yy) { 7204 pixel_data_type* end = dst + unpadded_row_size_in_elements; 7205 for (pixel_data_type* d = dst; d < end; d += channel_count) { 7206 *d = alpha_value; 7207 } 7208 dst += padded_row_size_in_elements; 7209 } 7210 } 7211 7212 void GLES2DecoderImpl::FinishReadPixels( 7213 const cmds::ReadPixels& c, 7214 GLuint buffer) { 7215 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels"); 7216 GLsizei width = c.width; 7217 GLsizei height = c.height; 7218 GLenum format = c.format; 7219 GLenum type = c.type; 7220 typedef cmds::ReadPixels::Result Result; 7221 uint32 pixels_size; 7222 Result* result = NULL; 7223 if (c.result_shm_id != 0) { 7224 result = GetSharedMemoryAs<Result*>( 7225 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 7226 if (!result) { 7227 if (buffer != 0) { 7228 glDeleteBuffersARB(1, &buffer); 7229 } 7230 return; 7231 } 7232 } 7233 GLES2Util::ComputeImageDataSizes( 7234 width, height, format, type, state_.pack_alignment, &pixels_size, 7235 NULL, NULL); 7236 void* pixels = GetSharedMemoryAs<void*>( 7237 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 7238 if (!pixels) { 7239 if (buffer != 0) { 7240 glDeleteBuffersARB(1, &buffer); 7241 } 7242 return; 7243 } 7244 7245 if (buffer != 0) { 7246 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); 7247 void* data; 7248 if (features().map_buffer_range) { 7249 data = glMapBufferRange( 7250 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT); 7251 } else { 7252 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); 7253 } 7254 memcpy(pixels, data, pixels_size); 7255 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't 7256 // have to restore the state. 7257 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); 7258 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7259 glDeleteBuffersARB(1, &buffer); 7260 } 7261 7262 if (result != NULL) { 7263 *result = true; 7264 } 7265 7266 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 7267 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 7268 if ((channels_exist & 0x0008) == 0 && 7269 workarounds().clear_alpha_in_readpixels) { 7270 // Set the alpha to 255 because some drivers are buggy in this regard. 7271 uint32 temp_size; 7272 7273 uint32 unpadded_row_size; 7274 uint32 padded_row_size; 7275 if (!GLES2Util::ComputeImageDataSizes( 7276 width, 2, format, type, state_.pack_alignment, &temp_size, 7277 &unpadded_row_size, &padded_row_size)) { 7278 return; 7279 } 7280 7281 uint32 channel_count = 0; 7282 uint32 alpha_channel = 0; 7283 switch (format) { 7284 case GL_RGBA: 7285 case GL_BGRA_EXT: 7286 channel_count = 4; 7287 alpha_channel = 3; 7288 break; 7289 case GL_ALPHA: 7290 channel_count = 1; 7291 alpha_channel = 0; 7292 break; 7293 } 7294 7295 if (channel_count > 0) { 7296 switch (type) { 7297 case GL_UNSIGNED_BYTE: 7298 WriteAlphaData<uint8>( 7299 pixels, height, channel_count, alpha_channel, unpadded_row_size, 7300 padded_row_size, 0xFF); 7301 break; 7302 case GL_FLOAT: 7303 WriteAlphaData<float>( 7304 pixels, height, channel_count, alpha_channel, unpadded_row_size, 7305 padded_row_size, 1.0f); 7306 break; 7307 case GL_HALF_FLOAT: 7308 WriteAlphaData<uint16>( 7309 pixels, height, channel_count, alpha_channel, unpadded_row_size, 7310 padded_row_size, 0x3C00); 7311 break; 7312 } 7313 } 7314 } 7315 } 7316 7317 7318 error::Error GLES2DecoderImpl::HandleReadPixels( 7319 uint32 immediate_data_size, const cmds::ReadPixels& c) { 7320 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels"); 7321 error::Error fbo_error = WillAccessBoundFramebufferForRead(); 7322 if (fbo_error != error::kNoError) 7323 return fbo_error; 7324 GLint x = c.x; 7325 GLint y = c.y; 7326 GLsizei width = c.width; 7327 GLsizei height = c.height; 7328 GLenum format = c.format; 7329 GLenum type = c.type; 7330 GLboolean async = c.async; 7331 if (width < 0 || height < 0) { 7332 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); 7333 return error::kNoError; 7334 } 7335 typedef cmds::ReadPixels::Result Result; 7336 uint32 pixels_size; 7337 if (!GLES2Util::ComputeImageDataSizes( 7338 width, height, format, type, state_.pack_alignment, &pixels_size, 7339 NULL, NULL)) { 7340 return error::kOutOfBounds; 7341 } 7342 void* pixels = GetSharedMemoryAs<void*>( 7343 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 7344 if (!pixels) { 7345 return error::kOutOfBounds; 7346 } 7347 Result* result = NULL; 7348 if (c.result_shm_id != 0) { 7349 result = GetSharedMemoryAs<Result*>( 7350 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 7351 if (!result) { 7352 return error::kOutOfBounds; 7353 } 7354 } 7355 7356 if (!validators_->read_pixel_format.IsValid(format)) { 7357 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format"); 7358 return error::kNoError; 7359 } 7360 if (!validators_->read_pixel_type.IsValid(type)) { 7361 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type"); 7362 return error::kNoError; 7363 } 7364 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB && 7365 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) { 7366 // format and type are acceptable enums but not guaranteed to be supported 7367 // for this framebuffer. Have to ask gl if they are valid. 7368 GLint preferred_format = 0; 7369 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format); 7370 GLint preferred_type = 0; 7371 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type); 7372 if (format != static_cast<GLenum>(preferred_format) || 7373 type != static_cast<GLenum>(preferred_type)) { 7374 LOCAL_SET_GL_ERROR( 7375 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible " 7376 "with the current read framebuffer"); 7377 return error::kNoError; 7378 } 7379 } 7380 if (width == 0 || height == 0) { 7381 return error::kNoError; 7382 } 7383 7384 // Get the size of the current fbo or backbuffer. 7385 gfx::Size max_size = GetBoundReadFrameBufferSize(); 7386 7387 int32 max_x; 7388 int32 max_y; 7389 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) { 7390 LOCAL_SET_GL_ERROR( 7391 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7392 return error::kNoError; 7393 } 7394 7395 if (!CheckBoundFramebuffersValid("glReadPixels")) { 7396 return error::kNoError; 7397 } 7398 7399 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels"); 7400 7401 ScopedResolvedFrameBufferBinder binder(this, false, true); 7402 7403 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) { 7404 // The user requested an out of range area. Get the results 1 line 7405 // at a time. 7406 uint32 temp_size; 7407 uint32 unpadded_row_size; 7408 uint32 padded_row_size; 7409 if (!GLES2Util::ComputeImageDataSizes( 7410 width, 2, format, type, state_.pack_alignment, &temp_size, 7411 &unpadded_row_size, &padded_row_size)) { 7412 LOCAL_SET_GL_ERROR( 7413 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7414 return error::kNoError; 7415 } 7416 7417 GLint dest_x_offset = std::max(-x, 0); 7418 uint32 dest_row_offset; 7419 if (!GLES2Util::ComputeImageDataSizes( 7420 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset, 7421 NULL, NULL)) { 7422 LOCAL_SET_GL_ERROR( 7423 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 7424 return error::kNoError; 7425 } 7426 7427 // Copy each row into the larger dest rect. 7428 int8* dst = static_cast<int8*>(pixels); 7429 GLint read_x = std::max(0, x); 7430 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x)); 7431 GLint read_width = read_end_x - read_x; 7432 for (GLint yy = 0; yy < height; ++yy) { 7433 GLint ry = y + yy; 7434 7435 // Clear the row. 7436 memset(dst, 0, unpadded_row_size); 7437 7438 // If the row is in range, copy it. 7439 if (ry >= 0 && ry < max_size.height() && read_width > 0) { 7440 glReadPixels( 7441 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); 7442 } 7443 dst += padded_row_size; 7444 } 7445 } else { 7446 if (async && features().use_async_readpixels) { 7447 GLuint buffer; 7448 glGenBuffersARB(1, &buffer); 7449 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); 7450 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); 7451 GLenum error = glGetError(); 7452 if (error == GL_NO_ERROR) { 7453 glReadPixels(x, y, width, height, format, type, 0); 7454 pending_readpixel_fences_.push(linked_ptr<FenceCallback>( 7455 new FenceCallback())); 7456 WaitForReadPixels(base::Bind( 7457 &GLES2DecoderImpl::FinishReadPixels, 7458 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr 7459 <GLES2DecoderImpl>(this), 7460 c, buffer)); 7461 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7462 return error::kNoError; 7463 } else { 7464 // On error, unbind pack buffer and fall through to sync readpixels 7465 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); 7466 } 7467 } 7468 glReadPixels(x, y, width, height, format, type, pixels); 7469 } 7470 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels"); 7471 if (error == GL_NO_ERROR) { 7472 if (result != NULL) { 7473 *result = true; 7474 } 7475 FinishReadPixels(c, 0); 7476 } 7477 7478 return error::kNoError; 7479 } 7480 7481 error::Error GLES2DecoderImpl::HandlePixelStorei( 7482 uint32 immediate_data_size, const cmds::PixelStorei& c) { 7483 GLenum pname = c.pname; 7484 GLenum param = c.param; 7485 if (!validators_->pixel_store.IsValid(pname)) { 7486 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname"); 7487 return error::kNoError; 7488 } 7489 switch (pname) { 7490 case GL_PACK_ALIGNMENT: 7491 case GL_UNPACK_ALIGNMENT: 7492 if (!validators_->pixel_store_alignment.IsValid(param)) { 7493 LOCAL_SET_GL_ERROR( 7494 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE"); 7495 return error::kNoError; 7496 } 7497 break; 7498 case GL_UNPACK_FLIP_Y_CHROMIUM: 7499 unpack_flip_y_ = (param != 0); 7500 return error::kNoError; 7501 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 7502 unpack_premultiply_alpha_ = (param != 0); 7503 return error::kNoError; 7504 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 7505 unpack_unpremultiply_alpha_ = (param != 0); 7506 return error::kNoError; 7507 default: 7508 break; 7509 } 7510 glPixelStorei(pname, param); 7511 switch (pname) { 7512 case GL_PACK_ALIGNMENT: 7513 state_.pack_alignment = param; 7514 break; 7515 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 7516 state_.pack_reverse_row_order = (param != 0); 7517 break; 7518 case GL_UNPACK_ALIGNMENT: 7519 state_.unpack_alignment = param; 7520 break; 7521 default: 7522 // Validation should have prevented us from getting here. 7523 NOTREACHED(); 7524 break; 7525 } 7526 return error::kNoError; 7527 } 7528 7529 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( 7530 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) { 7531 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); 7532 { 7533 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame"); 7534 } 7535 if (!supports_post_sub_buffer_) { 7536 LOCAL_SET_GL_ERROR( 7537 GL_INVALID_OPERATION, 7538 "glPostSubBufferCHROMIUM", "command not supported by surface"); 7539 return error::kNoError; 7540 } 7541 bool is_tracing; 7542 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"), 7543 &is_tracing); 7544 if (is_tracing) { 7545 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 7546 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId()); 7547 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer( 7548 is_offscreen ? offscreen_size_ : surface_->GetSize()); 7549 } 7550 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) { 7551 return error::kNoError; 7552 } else { 7553 LOG(ERROR) << "Context lost because PostSubBuffer failed."; 7554 return error::kLostContext; 7555 } 7556 } 7557 7558 error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM( 7559 uint32 immediate_data_size, 7560 const cmds::ScheduleOverlayPlaneCHROMIUM& c) { 7561 NOTIMPLEMENTED() << "Overlay supported isn't finished."; 7562 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, 7563 "glScheduleOverlayPlaneCHROMIUM", 7564 "function not implemented"); 7565 return error::kNoError; 7566 } 7567 7568 error::Error GLES2DecoderImpl::GetAttribLocationHelper( 7569 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 7570 const std::string& name_str) { 7571 if (!StringIsValidForGLES(name_str.c_str())) { 7572 LOCAL_SET_GL_ERROR( 7573 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); 7574 return error::kNoError; 7575 } 7576 Program* program = GetProgramInfoNotShader( 7577 client_id, "glGetAttribLocation"); 7578 if (!program) { 7579 return error::kNoError; 7580 } 7581 if (!program->IsValid()) { 7582 LOCAL_SET_GL_ERROR( 7583 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked"); 7584 return error::kNoError; 7585 } 7586 GLint* location = GetSharedMemoryAs<GLint*>( 7587 location_shm_id, location_shm_offset, sizeof(GLint)); 7588 if (!location) { 7589 return error::kOutOfBounds; 7590 } 7591 // Require the client to init this incase the context is lost and we are no 7592 // longer executing commands. 7593 if (*location != -1) { 7594 return error::kGenericError; 7595 } 7596 *location = program->GetAttribLocation(name_str); 7597 return error::kNoError; 7598 } 7599 7600 error::Error GLES2DecoderImpl::HandleGetAttribLocation( 7601 uint32 immediate_data_size, const cmds::GetAttribLocation& c) { 7602 Bucket* bucket = GetBucket(c.name_bucket_id); 7603 if (!bucket) { 7604 return error::kInvalidArguments; 7605 } 7606 std::string name_str; 7607 if (!bucket->GetAsString(&name_str)) { 7608 return error::kInvalidArguments; 7609 } 7610 return GetAttribLocationHelper( 7611 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7612 } 7613 7614 error::Error GLES2DecoderImpl::GetUniformLocationHelper( 7615 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 7616 const std::string& name_str) { 7617 if (!StringIsValidForGLES(name_str.c_str())) { 7618 LOCAL_SET_GL_ERROR( 7619 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); 7620 return error::kNoError; 7621 } 7622 Program* program = GetProgramInfoNotShader( 7623 client_id, "glGetUniformLocation"); 7624 if (!program) { 7625 return error::kNoError; 7626 } 7627 if (!program->IsValid()) { 7628 LOCAL_SET_GL_ERROR( 7629 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked"); 7630 return error::kNoError; 7631 } 7632 GLint* location = GetSharedMemoryAs<GLint*>( 7633 location_shm_id, location_shm_offset, sizeof(GLint)); 7634 if (!location) { 7635 return error::kOutOfBounds; 7636 } 7637 // Require the client to init this incase the context is lost an we are no 7638 // longer executing commands. 7639 if (*location != -1) { 7640 return error::kGenericError; 7641 } 7642 *location = program->GetUniformFakeLocation(name_str); 7643 return error::kNoError; 7644 } 7645 7646 error::Error GLES2DecoderImpl::HandleGetUniformLocation( 7647 uint32 immediate_data_size, const cmds::GetUniformLocation& c) { 7648 Bucket* bucket = GetBucket(c.name_bucket_id); 7649 if (!bucket) { 7650 return error::kInvalidArguments; 7651 } 7652 std::string name_str; 7653 if (!bucket->GetAsString(&name_str)) { 7654 return error::kInvalidArguments; 7655 } 7656 return GetUniformLocationHelper( 7657 c.program, c.location_shm_id, c.location_shm_offset, name_str); 7658 } 7659 7660 error::Error GLES2DecoderImpl::HandleGetString( 7661 uint32 immediate_data_size, const cmds::GetString& c) { 7662 GLenum name = static_cast<GLenum>(c.name); 7663 if (!validators_->string_type.IsValid(name)) { 7664 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name"); 7665 return error::kNoError; 7666 } 7667 const char* str = reinterpret_cast<const char*>(glGetString(name)); 7668 std::string extensions; 7669 switch (name) { 7670 case GL_VERSION: 7671 str = "OpenGL ES 2.0 Chromium"; 7672 break; 7673 case GL_SHADING_LANGUAGE_VERSION: 7674 str = "OpenGL ES GLSL ES 1.0 Chromium"; 7675 break; 7676 case GL_RENDERER: 7677 case GL_VENDOR: 7678 // Return the unmasked VENDOR/RENDERER string for WebGL contexts. 7679 // They are used by WEBGL_debug_renderer_info. 7680 if (!force_webgl_glsl_validation_) 7681 str = "Chromium"; 7682 break; 7683 case GL_EXTENSIONS: 7684 { 7685 // For WebGL contexts, strip out the OES derivatives and 7686 // EXT frag depth extensions if they have not been enabled. 7687 if (force_webgl_glsl_validation_) { 7688 extensions = feature_info_->extensions(); 7689 if (!derivatives_explicitly_enabled_) { 7690 size_t offset = extensions.find(kOESDerivativeExtension); 7691 if (std::string::npos != offset) { 7692 extensions.replace(offset, arraysize(kOESDerivativeExtension), 7693 std::string()); 7694 } 7695 } 7696 if (!frag_depth_explicitly_enabled_) { 7697 size_t offset = extensions.find(kEXTFragDepthExtension); 7698 if (std::string::npos != offset) { 7699 extensions.replace(offset, arraysize(kEXTFragDepthExtension), 7700 std::string()); 7701 } 7702 } 7703 if (!draw_buffers_explicitly_enabled_) { 7704 size_t offset = extensions.find(kEXTDrawBuffersExtension); 7705 if (std::string::npos != offset) { 7706 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension), 7707 std::string()); 7708 } 7709 } 7710 if (!shader_texture_lod_explicitly_enabled_) { 7711 size_t offset = extensions.find(kEXTShaderTextureLodExtension); 7712 if (std::string::npos != offset) { 7713 extensions.replace(offset, 7714 arraysize(kEXTShaderTextureLodExtension), 7715 std::string()); 7716 } 7717 } 7718 } else { 7719 extensions = feature_info_->extensions().c_str(); 7720 } 7721 if (supports_post_sub_buffer_) 7722 extensions += " GL_CHROMIUM_post_sub_buffer"; 7723 str = extensions.c_str(); 7724 } 7725 break; 7726 default: 7727 break; 7728 } 7729 Bucket* bucket = CreateBucket(c.bucket_id); 7730 bucket->SetFromString(str); 7731 return error::kNoError; 7732 } 7733 7734 error::Error GLES2DecoderImpl::HandleBufferData( 7735 uint32 immediate_data_size, const cmds::BufferData& c) { 7736 GLenum target = static_cast<GLenum>(c.target); 7737 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 7738 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 7739 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 7740 GLenum usage = static_cast<GLenum>(c.usage); 7741 const void* data = NULL; 7742 if (data_shm_id != 0 || data_shm_offset != 0) { 7743 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); 7744 if (!data) { 7745 return error::kOutOfBounds; 7746 } 7747 } 7748 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage); 7749 return error::kNoError; 7750 } 7751 7752 void GLES2DecoderImpl::DoBufferSubData( 7753 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { 7754 // Just delegate it. Some validation is actually done before this. 7755 buffer_manager()->ValidateAndDoBufferSubData( 7756 &state_, target, offset, size, data); 7757 } 7758 7759 bool GLES2DecoderImpl::ClearLevel( 7760 unsigned service_id, 7761 unsigned bind_target, 7762 unsigned target, 7763 int level, 7764 unsigned internal_format, 7765 unsigned format, 7766 unsigned type, 7767 int width, 7768 int height, 7769 bool is_texture_immutable) { 7770 uint32 channels = GLES2Util::GetChannelsForFormat(format); 7771 if (feature_info_->feature_flags().angle_depth_texture && 7772 (channels & GLES2Util::kDepth) != 0) { 7773 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D 7774 // on depth formats. 7775 GLuint fb = 0; 7776 glGenFramebuffersEXT(1, &fb); 7777 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); 7778 7779 bool have_stencil = (channels & GLES2Util::kStencil) != 0; 7780 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : 7781 GL_DEPTH_ATTACHMENT; 7782 7783 glFramebufferTexture2DEXT( 7784 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); 7785 // ANGLE promises a depth only attachment ok. 7786 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != 7787 GL_FRAMEBUFFER_COMPLETE) { 7788 return false; 7789 } 7790 glClearStencil(0); 7791 state_.SetDeviceStencilMaskSeparate(GL_FRONT, -1); 7792 state_.SetDeviceStencilMaskSeparate(GL_BACK, -1); 7793 glClearDepth(1.0f); 7794 state_.SetDeviceDepthMask(GL_TRUE); 7795 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false); 7796 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0)); 7797