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