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