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/image_manager.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/mailbox_manager.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/program_manager.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/renderbuffer_manager.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/shader_manager.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/texture_manager.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/transfer_buffer_manager.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextGroup::ContextGroup( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MailboxManager* mailbox_manager, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImageManager* image_manager, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MemoryTracker* memory_tracker, 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StreamTextureManager* stream_texture_manager, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bind_generates_resource) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager), 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_manager_(image_manager ? image_manager : new ImageManager), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_tracker_(memory_tracker), 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_texture_manager_(stream_texture_manager), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch( 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kEnforceGLMinimums)), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bind_generates_resource_(bind_generates_resource), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_attribs_(0u), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_units_(0u), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_image_units_(0u), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_texture_image_units_(0u), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_fragment_uniform_vectors_(0u), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_varying_vectors_(0u), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_uniform_vectors_(0u), 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_color_attachments_(1u), 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_draw_buffers_(1u), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_cache_(NULL), 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) feature_info_(new FeatureInfo()), 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) draw_buffer_(GL_BACK) { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransferBufferManager* manager = new TransferBufferManager(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_buffer_manager_.reset(manager); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->Initialize(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kBuffers].reset(new IdAllocator); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kFramebuffers].reset(new IdAllocator); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kProgramsAndShaders].reset( 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new NonReusedIdAllocator); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kRenderbuffers].reset(new IdAllocator); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kTextures].reset(new IdAllocator); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kQueries].reset(new IdAllocator); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id_namespaces_[id_namespaces::kVertexArrays].reset(new IdAllocator); 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch id_namespaces_[id_namespaces::kImages].reset(new IdAllocator); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void GetIntegerv(GLenum pname, uint32* var) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = 0; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetIntegerv(pname, &value); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *var = value; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextGroup::Initialize( 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLES2Decoder* decoder, 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisallowedFeatures& disallowed_features, 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* allowed_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) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!feature_info_->Initialize(disallowed_features, allowed_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) 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buffer_manager_.reset( 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new BufferManager(memory_tracker_.get(), feature_info_.get())); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) framebuffer_manager_.reset( 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new FramebufferManager(max_draw_buffers_, max_color_attachments_)); 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) renderbuffer_manager_.reset(new RenderbufferManager( 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) memory_tracker_.get(), max_renderbuffer_size, max_samples)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_manager_.reset(new ShaderManager()); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_manager_.reset(new ProgramManager(program_cache_)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lookup GL things we need to know. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kGLES2RequiredMinimumVertexAttribs = 8u; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeatureU( 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_VERTEX_ATTRIBS, kGLES2RequiredMinimumVertexAttribs, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_vertex_attribs_)) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "vertex attributes supported."; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLuint kGLES2RequiredMinimumTextureUnits = 8u; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeatureU( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kGLES2RequiredMinimumTextureUnits, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_texture_units_)) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "texture units supported."; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_texture_size = 0; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint max_cube_map_texture_size = 0; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinTextureSize = 2048; // GL actually says 64!?!? 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinCubeMapSize = 256; // GL actually says 16!?!? 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeature( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_TEXTURE_SIZE, kMinTextureSize, &max_texture_size) || 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !QueryGLFeature( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMinCubeMapSize, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_cube_map_texture_size)) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because maximum texture size" 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "is too small."; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_info_->workarounds().max_texture_size) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_size = std::min( 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_size, feature_info_->workarounds().max_texture_size); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (feature_info_->workarounds().max_cube_map_texture_size) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_cube_map_texture_size = std::min( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_cube_map_texture_size, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_info_->workarounds().max_cube_map_texture_size); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) texture_manager_.reset(new TextureManager(memory_tracker_.get(), 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) feature_info_.get(), 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_texture_size, 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_cube_map_texture_size)); 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) texture_manager_->set_framebuffer_manager(framebuffer_manager_.get()); 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch texture_manager_->set_stream_texture_manager(stream_texture_manager_); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinTextureImageUnits = 8; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinVertexTextureImageUnits = 0; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryGLFeatureU( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_TEXTURE_IMAGE_UNITS, kMinTextureImageUnits, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_texture_image_units_) || 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !QueryGLFeatureU( 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMinVertexTextureImageUnits, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_vertex_texture_image_units_)) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "texture units."; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &max_fragment_uniform_vectors_); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors_); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &max_vertex_uniform_vectors_); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv( 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max_fragment_uniform_vectors_); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_fragment_uniform_vectors_ /= 4; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VARYING_FLOATS, &max_varying_vectors_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_varying_vectors_ /= 4; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_vertex_uniform_vectors_); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_vertex_uniform_vectors_ /= 4; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinFragmentUniformVectors = 16; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinVaryingVectors = 8; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GLint kMinVertexUniformVectors = 128; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CheckGLFeatureU( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinFragmentUniformVectors, &max_fragment_uniform_vectors_) || 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !CheckGLFeatureU(kMinVaryingVectors, &max_varying_vectors_) || 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !CheckGLFeatureU( 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kMinVertexUniformVectors, &max_vertex_uniform_vectors_)) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "ContextGroup::Initialize failed because too few " 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "uniforms or varyings supported."; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(gman): Use workarounds similar to max_texture_size above to implement. 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL) { 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Some shaders in Skia needed more than the min. 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_fragment_uniform_vectors_ = 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::min(static_cast<uint32>(kMinFragmentUniformVectors * 2), 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_fragment_uniform_vectors_); 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_varying_vectors_ = 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::min(static_cast<uint32>(kMinVaryingVectors * 2), 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_varying_vectors_); 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_vertex_uniform_vectors_ = 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::min(static_cast<uint32>(kMinVertexUniformVectors * 2), 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) max_vertex_uniform_vectors_); 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!texture_manager_->Initialize()) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Context::Group::Initialize failed because texture manager " 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "failed to initialize."; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsNull(const base::WeakPtr<gles2::GLES2Decoder>& decoder) { 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return !decoder.get(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)template <typename T> 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class WeakPtrEquals { 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) explicit WeakPtrEquals(T* t) : t_(t) {} 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool operator()(const base::WeakPtr<T>& t) { 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return t.get() == t_; 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) T* const t_; 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace anonymous 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextGroup::HaveContexts() { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.erase(std::remove_if(decoders_.begin(), decoders_.end(), IsNull), 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.end()); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !decoders_.empty(); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) { 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoders_.erase(std::remove_if(decoders_.begin(), decoders_.end(), 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WeakPtrEquals<gles2::GLES2Decoder>(decoder)), 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_.end()); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we still have contexts do nothing. 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HaveContexts()) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_manager_ != NULL) { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_manager_->Destroy(have_context); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_manager_.reset(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (framebuffer_manager_ != NULL) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framebuffer_manager_->Destroy(have_context); 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (texture_manager_) 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) texture_manager_->set_framebuffer_manager(NULL); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) framebuffer_manager_.reset(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (renderbuffer_manager_ != NULL) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) renderbuffer_manager_->Destroy(have_context); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) renderbuffer_manager_.reset(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_manager_ != NULL) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_manager_->Destroy(have_context); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) texture_manager_.reset(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (program_manager_ != NULL) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_manager_->Destroy(have_context); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) program_manager_.reset(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shader_manager_ != NULL) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_manager_->Destroy(have_context); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shader_manager_.reset(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memory_tracker_ = NULL; 318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch stream_texture_manager_ = NULL; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdAllocatorInterface* ContextGroup::GetIdAllocator(unsigned namespace_id) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (namespace_id >= arraysize(id_namespaces_)) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return id_namespaces_[namespace_id].get(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 ContextGroup::GetMemRepresented() const { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 total = 0; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_manager_.get()) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total += buffer_manager_->mem_represented(); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (renderbuffer_manager_.get()) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total += renderbuffer_manager_->mem_represented(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (texture_manager_.get()) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total += texture_manager_->mem_represented(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return total; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextGroup::LoseContexts(GLenum reset_status) { 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t ii = 0; ii < decoders_.size(); ++ii) { 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (decoders_[ii].get()) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoders_[ii]->LoseContext(reset_status); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextGroup::~ContextGroup() { 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(!HaveContexts()); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::CheckGLFeature(GLint min_required, GLint* v) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = *v; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enforce_gl_minimums_) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = std::min(min_required, value); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value >= min_required; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::CheckGLFeatureU(GLint min_required, uint32* v) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = *v; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enforce_gl_minimums_) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = std::min(min_required, value); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return value >= min_required; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::QueryGLFeature( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum pname, GLint min_required, GLint* v) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint value = 0; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetIntegerv(pname, &value); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CheckGLFeature(min_required, v); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::QueryGLFeatureU( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLenum pname, GLint min_required, uint32* v) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 value = 0; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetIntegerv(pname, &value); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = CheckGLFeatureU(min_required, &value); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *v = value; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gles2 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 388