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