context_group.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/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,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool bind_generates_resource)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      image_manager_(image_manager ? image_manager : new ImageManager),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memory_tracker_(memory_tracker),
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),
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      feature_info_(new FeatureInfo()),
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      draw_buffer_(GL_BACK) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransferBufferManager* manager = new TransferBufferManager();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    transfer_buffer_manager_.reset(manager);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager->Initialize();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kBuffers].reset(new IdAllocator);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kFramebuffers].reset(new IdAllocator);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kProgramsAndShaders].reset(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new NonReusedIdAllocator);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kRenderbuffers].reset(new IdAllocator);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kTextures].reset(new IdAllocator);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kQueries].reset(new IdAllocator);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  id_namespaces_[id_namespaces::kVertexArrays].reset(new IdAllocator);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void GetIntegerv(GLenum pname, uint32* var) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint value = 0;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetIntegerv(pname, &value);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *var = value;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextGroup::Initialize(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLES2Decoder* decoder,
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DisallowedFeatures& disallowed_features,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* allowed_features) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we've already initialized the group just add the context.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (HaveContexts()) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!feature_info_->Initialize(disallowed_features, allowed_features)) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because FeatureInfo "
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "initialization failed.";
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinRenderbufferSize = 512;  // GL says 1 pixel!
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint max_renderbuffer_size = 0;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!QueryGLFeature(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_RENDERBUFFER_SIZE, kMinRenderbufferSize,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &max_renderbuffer_size)) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because maximum "
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "renderbuffer size too small.";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint max_samples = 0;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (feature_info_->feature_flags().chromium_framebuffer_multisample) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (feature_info_->feature_flags().ext_draw_buffers) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &max_color_attachments_);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (max_color_attachments_ < 1)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_color_attachments_ = 1;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buffers_);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (max_draw_buffers_ < 1)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_draw_buffers_ = 1;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_buffer_ = GL_BACK;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  buffer_manager_.reset(new BufferManager(
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memory_tracker_, feature_info_.get()));
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  framebuffer_manager_.reset(
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FramebufferManager(max_draw_buffers_, max_color_attachments_));
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  renderbuffer_manager_.reset(new RenderbufferManager(memory_tracker_,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      max_renderbuffer_size,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                      max_samples));
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shader_manager_.reset(new ShaderManager());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  program_manager_.reset(new ProgramManager(program_cache_));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lookup GL things we need to know.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kGLES2RequiredMinimumVertexAttribs = 8u;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!QueryGLFeatureU(
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_VERTEX_ATTRIBS, kGLES2RequiredMinimumVertexAttribs,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &max_vertex_attribs_)) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because too few "
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "vertex attributes supported.";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kGLES2RequiredMinimumTextureUnits = 8u;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!QueryGLFeatureU(
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kGLES2RequiredMinimumTextureUnits,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &max_texture_units_)) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because too few "
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "texture units supported.";
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint max_texture_size = 0;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint max_cube_map_texture_size = 0;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinTextureSize = 2048;  // GL actually says 64!?!?
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinCubeMapSize = 256;  // GL actually says 16!?!?
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!QueryGLFeature(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_TEXTURE_SIZE, kMinTextureSize, &max_texture_size) ||
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !QueryGLFeature(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMinCubeMapSize,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &max_cube_map_texture_size)) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because maximum texture size"
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "is too small.";
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (feature_info_->workarounds().max_texture_size) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_texture_size = std::min(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        max_texture_size, feature_info_->workarounds().max_texture_size);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (feature_info_->workarounds().max_cube_map_texture_size) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_cube_map_texture_size = std::min(
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        max_cube_map_texture_size,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        feature_info_->workarounds().max_cube_map_texture_size);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  texture_manager_.reset(new TextureManager(memory_tracker_,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            feature_info_.get(),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            max_texture_size,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            max_cube_map_texture_size));
17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture_manager_->set_framebuffer_manager(framebuffer_manager_.get());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinTextureImageUnits = 8;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinVertexTextureImageUnits = 0;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!QueryGLFeatureU(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_TEXTURE_IMAGE_UNITS, kMinTextureImageUnits,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &max_texture_image_units_) ||
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !QueryGLFeatureU(
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMinVertexTextureImageUnits,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &max_vertex_texture_image_units_)) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because too few "
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "texture units.";
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &max_fragment_uniform_vectors_);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetIntegerv(GL_MAX_VARYING_VECTORS, &max_varying_vectors_);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &max_vertex_uniform_vectors_);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetIntegerv(
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max_fragment_uniform_vectors_);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_fragment_uniform_vectors_ /= 4;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetIntegerv(GL_MAX_VARYING_FLOATS, &max_varying_vectors_);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_varying_vectors_ /= 4;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &max_vertex_uniform_vectors_);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    max_vertex_uniform_vectors_ /= 4;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinFragmentUniformVectors = 16;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinVaryingVectors = 8;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kMinVertexUniformVectors = 128;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CheckGLFeatureU(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMinFragmentUniformVectors, &max_fragment_uniform_vectors_) ||
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !CheckGLFeatureU(kMinVaryingVectors, &max_varying_vectors_) ||
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !CheckGLFeatureU(
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kMinVertexUniformVectors, &max_vertex_uniform_vectors_)) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "ContextGroup::Initialize failed because too few "
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "uniforms or varyings supported.";
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(gman): Use workarounds similar to max_texture_size above to implement.
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (gfx::GetGLImplementation() == gfx::kGLImplementationOSMesaGL) {
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Some shaders in Skia needed more than the min.
21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    max_fragment_uniform_vectors_ =
22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       std::min(static_cast<uint32>(kMinFragmentUniformVectors * 2),
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                max_fragment_uniform_vectors_);
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    max_varying_vectors_ =
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       std::min(static_cast<uint32>(kMinVaryingVectors * 2),
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                max_varying_vectors_);
22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    max_vertex_uniform_vectors_ =
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       std::min(static_cast<uint32>(kMinVertexUniformVectors * 2),
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                max_vertex_uniform_vectors_);
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!texture_manager_->Initialize()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Context::Group::Initialize failed because texture manager "
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "failed to initialize.";
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoders_.push_back(base::AsWeakPtr<GLES2Decoder>(decoder));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsNull(const base::WeakPtr<gles2::GLES2Decoder>& decoder) {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !decoder;
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace anonymous
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ContextGroup::HaveContexts() {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoders_.erase(std::remove_if(decoders_.begin(), decoders_.end(), IsNull),
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  decoders_.end());
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !decoders_.empty();
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextGroup::Destroy(GLES2Decoder* decoder, bool have_context) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoders_.erase(std::remove(decoders_.begin(), decoders_.end(), decoder),
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  decoders_.end());
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we still have contexts do nothing.
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (HaveContexts()) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (buffer_manager_ != NULL) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer_manager_->Destroy(have_context);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer_manager_.reset();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (framebuffer_manager_ != NULL) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framebuffer_manager_->Destroy(have_context);
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (texture_manager_)
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      texture_manager_->set_framebuffer_manager(NULL);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    framebuffer_manager_.reset();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (renderbuffer_manager_ != NULL) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderbuffer_manager_->Destroy(have_context);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderbuffer_manager_.reset();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (texture_manager_ != NULL) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mailbox_manager_->DestroyOwnedTextures(texture_manager_.get(),
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           have_context);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_manager_->Destroy(have_context);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_manager_.reset();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (program_manager_ != NULL) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    program_manager_->Destroy(have_context);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    program_manager_.reset();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (shader_manager_ != NULL) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shader_manager_->Destroy(have_context);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shader_manager_.reset();
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memory_tracker_ = NULL;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdAllocatorInterface* ContextGroup::GetIdAllocator(unsigned namespace_id) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (namespace_id >= arraysize(id_namespaces_))
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id_namespaces_[namespace_id].get();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 ContextGroup::GetMemRepresented() const {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 total = 0;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (buffer_manager_.get())
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total += buffer_manager_->mem_represented();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (renderbuffer_manager_.get())
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total += renderbuffer_manager_->mem_represented();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (texture_manager_.get())
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total += texture_manager_->mem_represented();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ContextGroup::LoseContexts(GLenum reset_status) {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t ii = 0; ii < decoders_.size(); ++ii) {
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (decoders_[ii]) {
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      decoders_[ii]->LoseContext(reset_status);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextGroup::~ContextGroup() {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!HaveContexts());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::CheckGLFeature(GLint min_required, GLint* v) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint value = *v;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enforce_gl_minimums_) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value = std::min(min_required, value);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *v = value;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value >= min_required;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::CheckGLFeatureU(GLint min_required, uint32* v) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint value = *v;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enforce_gl_minimums_) {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value = std::min(min_required, value);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *v = value;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value >= min_required;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::QueryGLFeature(
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum pname, GLint min_required, GLint* v) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint value = 0;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGetIntegerv(pname, &value);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *v = value;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckGLFeature(min_required, v);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ContextGroup::QueryGLFeatureU(
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum pname, GLint min_required, uint32* v) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 value = 0;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetIntegerv(pname, &value);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = CheckGLFeatureU(min_required, &value);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *v = value;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
366