15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/context_group.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_info.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/id_allocator.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/buffer_manager.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/framebuffer_manager.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gles2_cmd_decoder.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_switches.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/mailbox_manager.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/program_manager.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/renderbuffer_manager.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/shader_manager.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/texture_manager.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/transfer_buffer_manager.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextGroup::ContextGroup( 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<MailboxManager>& mailbox_manager, 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<MemoryTracker>& memory_tracker, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<ShaderTranslatorCache>& shader_translator_cache, 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<FeatureInfo>& feature_info, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bind_generates_resource) 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : mailbox_manager_(mailbox_manager), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_tracker_(memory_tracker), 38c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch shader_translator_cache_(shader_translator_cache), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kEnforceGLMinimums)), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bind_generates_resource_(bind_generates_resource), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_attribs_(0u), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_units_(0u), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_image_units_(0u), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_texture_image_units_(0u), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_fragment_uniform_vectors_(0u), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_varying_vectors_(0u), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_uniform_vectors_(0u), 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_color_attachments_(1u), 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_draw_buffers_(1u), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_cache_(NULL), 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci feature_info_(feature_info), 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) draw_buffer_(GL_BACK) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!mailbox_manager_.get()) 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci mailbox_manager_ = new MailboxManager; 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!feature_info.get()) 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci feature_info_ = new FeatureInfo; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransferBufferManager* manager = new TransferBufferManager(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_buffer_manager_.reset(manager); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->Initialize(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kBuffers].reset(new IdAllocator); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kFramebuffers].reset(new IdAllocator); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kProgramsAndShaders].reset( 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new NonReusedIdAllocator); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kRenderbuffers].reset(new IdAllocator); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kTextures].reset(new IdAllocator); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kQueries].reset(new IdAllocator); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kVertexArrays].reset(new IdAllocator); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void GetIntegerv(GLenum pname, uint32* var) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = 0; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetIntegerv(pname, &value); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *var = value; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextGroup::Initialize( 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Decoder* decoder, 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const DisallowedFeatures& disallowed_features) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we've already initialized the group just add the context. 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HaveContexts()) { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!feature_info_->Initialize(disallowed_features)) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because FeatureInfo " 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "initialization failed."; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinRenderbufferSize = 512; // GL says 1 pixel! 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_renderbuffer_size = 0; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeature( 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_RENDERBUFFER_SIZE, kMinRenderbufferSize, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_renderbuffer_size)) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because maximum " 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "renderbuffer size too small."; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_samples = 0; 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (feature_info_->feature_flags().chromium_framebuffer_multisample || 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch feature_info_->feature_flags().multisampled_render_to_texture) { 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (feature_info_->feature_flags( 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ).use_img_for_multisampled_render_to_texture) { 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch glGetIntegerv(GL_MAX_SAMPLES_IMG, &max_samples); 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else { 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch glGetIntegerv(GL_MAX_SAMPLES, &max_samples); 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (feature_info_->feature_flags().ext_draw_buffers) { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &max_color_attachments_); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (max_color_attachments_ < 1) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_color_attachments_ = 1; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buffers_); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (max_draw_buffers_ < 1) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_draw_buffers_ = 1; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) draw_buffer_ = GL_BACK; 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const bool depth24_supported = feature_info_->feature_flags().oes_depth24; 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buffer_manager_.reset( 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new BufferManager(memory_tracker_.get(), feature_info_.get())); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framebuffer_manager_.reset( 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new FramebufferManager(max_draw_buffers_, max_color_attachments_)); 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) renderbuffer_manager_.reset(new RenderbufferManager( 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) memory_tracker_.get(), max_renderbuffer_size, max_samples, 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) depth24_supported)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_manager_.reset(new ShaderManager()); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lookup GL things we need to know. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kGLES2RequiredMinimumVertexAttribs = 8u; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeatureU( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_VERTEX_ATTRIBS, kGLES2RequiredMinimumVertexAttribs, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_vertex_attribs_)) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "vertex attributes supported."; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint kGLES2RequiredMinimumTextureUnits = 8u; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeatureU( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kGLES2RequiredMinimumTextureUnits, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_texture_units_)) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "texture units supported."; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_texture_size = 0; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_cube_map_texture_size = 0; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinTextureSize = 2048; // GL actually says 64!?!? 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinCubeMapSize = 256; // GL actually says 16!?!? 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeature( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_TEXTURE_SIZE, kMinTextureSize, &max_texture_size) || 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !QueryGLFeature( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMinCubeMapSize, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_cube_map_texture_size)) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because maximum texture size" 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "is too small."; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_info_->workarounds().max_texture_size) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_size = std::min( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_size, feature_info_->workarounds().max_texture_size); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_info_->workarounds().max_cube_map_texture_size) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_cube_map_texture_size = std::min( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_cube_map_texture_size, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_info_->workarounds().max_cube_map_texture_size); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) texture_manager_.reset(new TextureManager(memory_tracker_.get(), 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_info_.get(), 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_size, 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch max_cube_map_texture_size, 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bind_generates_resource_)); 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) texture_manager_->set_framebuffer_manager(framebuffer_manager_.get()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinTextureImageUnits = 8; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinVertexTextureImageUnits = 0; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeatureU( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_TEXTURE_IMAGE_UNITS, kMinTextureImageUnits, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_texture_image_units_) || 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !QueryGLFeatureU( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMinVertexTextureImageUnits, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_vertex_texture_image_units_)) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "texture units."; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_fragment_uniform_vectors_); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors_); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &max_vertex_uniform_vectors_); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv( 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max_fragment_uniform_vectors_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_fragment_uniform_vectors_ /= 4; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VARYING_FLOATS, &max_varying_vectors_); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_varying_vectors_ /= 4; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_vertex_uniform_vectors_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_uniform_vectors_ /= 4; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinFragmentUniformVectors = 16; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinVaryingVectors = 8; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinVertexUniformVectors = 128; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CheckGLFeatureU( 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinFragmentUniformVectors, &max_fragment_uniform_vectors_) || 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !CheckGLFeatureU(kMinVaryingVectors, &max_varying_vectors_) || 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !CheckGLFeatureU( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinVertexUniformVectors, &max_vertex_uniform_vectors_)) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "uniforms or varyings supported."; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Some shaders in Skia need more than the min available vertex and 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // fragment shader uniform vectors in case of OSMesa GL Implementation 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (feature_info_->workarounds().max_fragment_uniform_vectors) { 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch max_fragment_uniform_vectors_ = std::min( 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch max_fragment_uniform_vectors_, 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static_cast<uint32>( 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch feature_info_->workarounds().max_fragment_uniform_vectors)); 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (feature_info_->workarounds().max_varying_vectors) { 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch max_varying_vectors_ = std::min( 2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch max_varying_vectors_, 2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static_cast<uint32>(feature_info_->workarounds().max_varying_vectors)); 2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (feature_info_->workarounds().max_vertex_uniform_vectors) { 24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_vertex_uniform_vectors_ = 2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::min(max_vertex_uniform_vectors_, 2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static_cast<uint32>( 2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch feature_info_->workarounds().max_vertex_uniform_vectors)); 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) program_manager_.reset(new ProgramManager( 24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) program_cache_, max_varying_vectors_)); 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!texture_manager_->Initialize()) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Context::Group::Initialize failed because texture manager " 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "failed to initialize."; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder)); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsNull(const base::WeakPtr<gles2::GLES2Decoder>& decoder) { 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !decoder.get(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template <typename T> 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WeakPtrEquals { 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit WeakPtrEquals(T* t) : t_(t) {} 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool operator()(const base::WeakPtr<T>& t) { 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return t.get() == t_; 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) T* const t_; 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace anonymous 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextGroup::HaveContexts() { 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.erase(std::remove_if(decoders_.begin(), decoders_.end(), IsNull), 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.end()); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !decoders_.empty(); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoders_.erase(std::remove_if(decoders_.begin(), decoders_.end(), 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WeakPtrEquals<gles2::GLES2Decoder>(decoder)), 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.end()); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we still have contexts do nothing. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HaveContexts()) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_manager_ != NULL) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_manager_->Destroy(have_context); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_manager_.reset(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (framebuffer_manager_ != NULL) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framebuffer_manager_->Destroy(have_context); 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (texture_manager_) 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) texture_manager_->set_framebuffer_manager(NULL); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framebuffer_manager_.reset(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (renderbuffer_manager_ != NULL) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) renderbuffer_manager_->Destroy(have_context); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) renderbuffer_manager_.reset(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_manager_ != NULL) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_manager_->Destroy(have_context); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_manager_.reset(); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (program_manager_ != NULL) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_manager_->Destroy(have_context); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_manager_.reset(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shader_manager_ != NULL) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_manager_->Destroy(have_context); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_manager_.reset(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_tracker_ = NULL; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdAllocatorInterface* ContextGroup::GetIdAllocator(unsigned namespace_id) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (namespace_id >= arraysize(id_namespaces_)) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return id_namespaces_[namespace_id].get(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 ContextGroup::GetMemRepresented() const { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 total = 0; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_manager_.get()) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total += buffer_manager_->mem_represented(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (renderbuffer_manager_.get()) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total += renderbuffer_manager_->mem_represented(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_manager_.get()) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total += texture_manager_->mem_represented(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextGroup::LoseContexts(GLenum reset_status) { 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t ii = 0; ii < decoders_.size(); ++ii) { 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (decoders_[ii].get()) { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_[ii]->LoseContext(reset_status); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextGroup::~ContextGroup() { 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!HaveContexts()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::CheckGLFeature(GLint min_required, GLint* v) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = *v; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enforce_gl_minimums_) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = std::min(min_required, value); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value >= min_required; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::CheckGLFeatureU(GLint min_required, uint32* v) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = *v; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enforce_gl_minimums_) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = std::min(min_required, value); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value >= min_required; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::QueryGLFeature( 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum pname, GLint min_required, GLint* v) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = 0; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetIntegerv(pname, &value); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CheckGLFeature(min_required, v); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::QueryGLFeatureU( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum pname, GLint min_required, uint32* v) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 value = 0; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(pname, &value); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = CheckGLFeatureU(min_required, &value); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gles2 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 398