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