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/texture_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bits.h"
7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/error_state.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/feature_info.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/service/framebuffer_manager.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/mailbox_manager.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/service/stream_texture_manager.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static size_t GLTargetToFaceIndex(GLenum target) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (target) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_2D:
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_EXTERNAL_OES:
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_RECTANGLE_ARB:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 2;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 3;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 4;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 5;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static size_t FaceIndexToGLTarget(size_t index) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (index) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 1:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 2:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 3:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 4:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 5:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TextureManager::DestructionObserver::DestructionObserver() {}
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TextureManager::DestructionObserver::~DestructionObserver() {}
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextureManager::~TextureManager() {
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FOR_EACH_OBSERVER(DestructionObserver,
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    destruction_observers_,
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    OnTextureManagerDestroying(this));
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(textures_.empty());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this triggers, that means something is keeping a reference to
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a Texture belonging to this.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(texture_count_, 0u);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(0, num_unrenderable_textures_);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(0, num_unsafe_textures_);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(0, num_uncleared_mips_);
82294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  DCHECK_EQ(0, num_images_);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureManager::Destroy(bool have_context) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  have_context_ = have_context;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  textures_.clear();
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int ii = 0; ii < kNumDefaultTextures; ++ii) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_textures_[ii] = NULL;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (have_context) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glDeleteTextures(arraysize(black_texture_ids_), black_texture_ids_);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, memory_tracker_managed_->GetMemRepresented());
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(0u, memory_tracker_unmanaged_->GetMemRepresented());
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Texture::Texture(GLuint service_id)
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : mailbox_manager_(NULL),
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      memory_tracking_ref_(NULL),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service_id_(service_id),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cleared_(true),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_uncleared_mips_(0),
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_(0),
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      min_filter_(GL_NEAREST_MIPMAP_LINEAR),
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mag_filter_(GL_LINEAR),
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrap_s_(GL_REPEAT),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrap_t_(GL_REPEAT),
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      usage_(GL_NONE),
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pool_(GL_TEXTURE_POOL_UNMANAGED_CHROMIUM),
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_level_set_(-1),
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      texture_complete_(false),
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cube_complete_(false),
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      npot_(false),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_been_bound_(false),
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      framebuffer_attachment_count_(0),
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stream_texture_(false),
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      immutable_(false),
121294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org      has_images_(false),
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      estimated_size_(0),
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      can_render_condition_(CAN_RENDER_ALWAYS) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Texture::~Texture() {
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (mailbox_manager_)
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    mailbox_manager_->TextureDeleted(this);
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::AddTextureRef(TextureRef* ref) {
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(refs_.find(ref) == refs_.end());
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  refs_.insert(ref);
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!memory_tracking_ref_) {
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    memory_tracking_ref_ = ref;
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GetMemTracker()->TrackMemAlloc(estimated_size());
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::RemoveTextureRef(TextureRef* ref, bool have_context) {
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (memory_tracking_ref_ == ref) {
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GetMemTracker()->TrackMemFree(estimated_size());
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    memory_tracking_ref_ = NULL;
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  size_t result = refs_.erase(ref);
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_EQ(result, 1u);
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (refs_.empty()) {
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (have_context) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLuint id = service_id();
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      glDeleteTextures(1, &id);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    delete this;
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else if (memory_tracking_ref_ == NULL) {
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(piman): tune ownership semantics for cross-context group shared
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // textures.
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    memory_tracking_ref_ = *refs_.begin();
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GetMemTracker()->TrackMemAlloc(estimated_size());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MemoryTypeTracker* Texture::GetMemTracker() {
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(memory_tracking_ref_);
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return memory_tracking_ref_->manager()->GetMemTracker(pool_);
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Texture::LevelInfo::LevelInfo()
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cleared(true),
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target(0),
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level(-1),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal_format(0),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width(0),
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height(0),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      depth(0),
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      border(0),
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format(0),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type(0),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      estimated_size(0) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Texture::LevelInfo::LevelInfo(const LevelInfo& rhs)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cleared(rhs.cleared),
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target(rhs.target),
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level(rhs.level),
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      internal_format(rhs.internal_format),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width(rhs.width),
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height(rhs.height),
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      depth(rhs.depth),
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      border(rhs.border),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      format(rhs.format),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type(rhs.type),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      image(rhs.image),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      estimated_size(rhs.estimated_size) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Texture::LevelInfo::~LevelInfo() {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Texture::CanRenderCondition Texture::GetCanRenderCondition() const {
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (target_ == 0)
20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return CAN_RENDER_ALWAYS;
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (target_ == GL_TEXTURE_EXTERNAL_OES) {
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!IsStreamTexture()) {
20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_NEVER;
20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } else {
20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (level_infos_.empty()) {
20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_NEVER;
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const Texture::LevelInfo& first_face = level_infos_[0][0];
21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (first_face.width == 0 ||
21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        first_face.height == 0 ||
21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        first_face.depth == 0) {
21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_NEVER;
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool needs_mips = NeedsMips();
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needs_mips) {
22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (!texture_complete())
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_NEVER;
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (target_ == GL_TEXTURE_CUBE_MAP && !cube_complete())
22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_NEVER;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool is_npot_compatible = !needs_mips &&
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      wrap_s_ == GL_CLAMP_TO_EDGE &&
22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      wrap_t_ == GL_CLAMP_TO_EDGE;
23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!is_npot_compatible) {
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (target_ == GL_TEXTURE_RECTANGLE_ARB)
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_NEVER;
23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    else if (npot())
23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return CAN_RENDER_ONLY_IF_NPOT;
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return CAN_RENDER_ALWAYS;
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool Texture::CanRender(const FeatureInfo* feature_info) const {
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  switch (can_render_condition_) {
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case CAN_RENDER_ALWAYS:
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return true;
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case CAN_RENDER_NEVER:
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return false;
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case CAN_RENDER_ONLY_IF_NPOT:
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      break;
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return feature_info->feature_flags().npot_ok;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Texture::AddToSignature(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FeatureInfo* feature_info,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target,
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* signature) const {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(feature_info);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(signature);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(level, 0);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_.size());
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(level),
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_[GLTargetToFaceIndex(target)].size());
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Texture::LevelInfo& info =
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level_infos_[GLTargetToFaceIndex(target)][level];
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *signature += base::StringPrintf(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "|Texture|target=%04x|level=%d|internal_format=%04x"
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "|width=%d|height=%d|depth=%d|border=%d|format=%04x|type=%04x"
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "|image=%d|canrender=%d|canrenderto=%d|npot_=%d"
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "|min_filter=%04x|mag_filter=%04x|wrap_s=%04x|wrap_t=%04x"
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "|usage=%04x",
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target, level, info.internal_format,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.width, info.height, info.depth, info.border,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.format, info.type, info.image.get() != NULL,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CanRender(feature_info), CanRenderTo(), npot_,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      min_filter_, mag_filter_, wrap_s_, wrap_t_,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      usage_);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Texture::SetMailboxManager(MailboxManager* mailbox_manager) {
282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(!mailbox_manager_ || mailbox_manager_ == mailbox_manager);
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  mailbox_manager_ = mailbox_manager;
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::MarkMipmapsGenerated(
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FeatureInfo* feature_info) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CanGenerateMipmaps(feature_info)) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Texture::LevelInfo& info1 = level_infos_[ii][0];
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei width = info1.width;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei height = info1.height;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei depth = info1.depth;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D :
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               FaceIndexToGLTarget(ii);
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int num_mips = TextureManager::ComputeMipMapCount(width, height, depth);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int level = 1; level < num_mips; ++level) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width = std::max(1, width >> 1);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height = std::max(1, height >> 1);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      depth = std::max(1, depth >> 1);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetLevelInfo(feature_info,
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   target,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   level,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   info1.internal_format,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   width,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   height,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   depth,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   info1.border,
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   info1.format,
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   info1.type,
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   true);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::SetTarget(
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const FeatureInfo* feature_info, GLenum target, GLint max_levels) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(0u, target_);  // you can only set this once.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target_ = target;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  level_infos_.resize(num_faces);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < num_faces; ++ii) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    level_infos_[ii].resize(max_levels);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ARB) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    min_filter_ = GL_LINEAR;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (target == GL_TEXTURE_EXTERNAL_OES) {
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    immutable_ = true;
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Update(feature_info);
33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateCanRenderCondition();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::CanGenerateMipmaps(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FeatureInfo* feature_info) const {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((npot() && !feature_info->feature_flags().npot_ok) ||
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level_infos_.empty() ||
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_ == GL_TEXTURE_EXTERNAL_OES ||
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_ == GL_TEXTURE_RECTANGLE_ARB) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can't generate mips for depth or stencil textures.
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Texture::LevelInfo& first = level_infos_[0][0];
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 channels = GLES2Util::GetChannelsForFormat(first.format);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channels & (GLES2Util::kDepth | GLES2Util::kStencil)) {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gman): Check internal_format, format and type.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const LevelInfo& info = level_infos_[ii][0];
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if ((info.target == 0) || (info.width != first.width) ||
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        (info.height != first.height) || (info.depth != 1) ||
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (info.format != first.format) ||
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (info.internal_format != first.internal_format) ||
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (info.type != first.type) ||
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        feature_info->validators()->compressed_texture_format.IsValid(
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            info.internal_format) ||
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        info.image.get()) {
369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return false;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Texture::SetLevelCleared(GLenum target, GLint level, bool cleared) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(level, 0);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_.size());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(level),
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_[GLTargetToFaceIndex(target)].size());
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Texture::LevelInfo& info =
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level_infos_[GLTargetToFaceIndex(target)][level];
38390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateMipCleared(&info, cleared);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCleared();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Texture::UpdateCleared() {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level_infos_.empty()) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Texture::LevelInfo& first_face = level_infos_[0][0];
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int levels_needed = TextureManager::ComputeMipMapCount(
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_face.width, first_face.height, first_face.depth);
39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool cleared = true;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (GLint jj = 0; jj < levels_needed; ++jj) {
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const Texture::LevelInfo& info = level_infos_[ii][jj];
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (info.width > 0 && info.height > 0 && info.depth > 0 &&
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !info.cleared) {
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        cleared = false;
40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        break;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
40690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateSafeToRenderFrom(cleared);
40790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
40890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::UpdateSafeToRenderFrom(bool cleared) {
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (cleared_ == cleared)
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  cleared_ = cleared;
41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int delta = cleared ? -1 : +1;
41490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    (*it)->manager()->UpdateSafeToRenderFrom(delta);
41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::UpdateMipCleared(LevelInfo* info, bool cleared) {
41990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (info->cleared == cleared)
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  info->cleared = cleared;
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int delta = cleared ? -1 : +1;
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  num_uncleared_mips_ += delta;
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    (*it)->manager()->UpdateUnclearedMips(delta);
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::UpdateCanRenderCondition() {
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  CanRenderCondition can_render_condition = GetCanRenderCondition();
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (can_render_condition_ == can_render_condition)
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return;
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    (*it)->manager()->UpdateCanRenderCondition(can_render_condition_,
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                               can_render_condition);
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  can_render_condition_ = can_render_condition;
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
438294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.orgvoid Texture::UpdateHasImages() {
439294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  if (level_infos_.empty())
440294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    return;
441294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org
442294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  bool has_images = false;
443294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
444294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    for (size_t jj = 0; jj < level_infos_[ii].size(); ++jj) {
445294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org      const Texture::LevelInfo& info = level_infos_[ii][jj];
446294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org      if (info.image.get() != NULL) {
447294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org        has_images = true;
448294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org        break;
449294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org      }
450294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    }
451294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  }
452294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org
453294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  if (has_images_ == has_images)
454294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    return;
455294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  has_images_ = has_images;
456294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  int delta = has_images ? +1 : -1;
457294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
458294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    (*it)->manager()->UpdateNumImages(delta);
459294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org}
460294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Texture::IncAllFramebufferStateChangeCount() {
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  for (RefSet::iterator it = refs_.begin(); it != refs_.end(); ++it)
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    (*it)->manager()->IncFramebufferStateChangeCount();
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Texture::SetLevelInfo(
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FeatureInfo* feature_info,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum internal_format,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei width,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei height,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei depth,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint border,
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum format,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum type,
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool cleared) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(level, 0);
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_.size());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(level),
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_[GLTargetToFaceIndex(target)].size());
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(width, 0);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(height, 0);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(depth, 0);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Texture::LevelInfo& info =
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level_infos_[GLTargetToFaceIndex(target)][level];
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.target = target;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.level = level;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.internal_format = internal_format;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.width = width;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.height = height;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.depth = depth;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.border = border;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.format = format;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.type = type;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.image = 0;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  estimated_size_ -= info.estimated_size;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLES2Util::ComputeImageDataSizes(
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width, height, format, type, 4, &info.estimated_size, NULL, NULL);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  estimated_size_ += info.estimated_size;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateMipCleared(&info, cleared);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_level_set_ = std::max(max_level_set_, level);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Update(feature_info);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCleared();
50890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateCanRenderCondition();
509294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  UpdateHasImages();
51090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsAttachedToFramebuffer()) {
51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // TODO(gman): If textures tracked which framebuffers they were attached to
51290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // we could just mark those framebuffers as not complete.
51390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    IncAllFramebufferStateChangeCount();
51490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::ValidForTexture(
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLint target,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint xoffset,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint yoffset,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei width,
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei height,
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum format,
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum type) const {
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t face_index = GLTargetToFaceIndex(target);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level >= 0 && face_index < level_infos_.size() &&
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<size_t>(level) < level_infos_[face_index].size()) {
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level];
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 right;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 top;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SafeAddInt32(xoffset, width, &right) &&
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           SafeAddInt32(yoffset, height, &top) &&
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           xoffset >= 0 &&
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           yoffset >= 0 &&
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           right <= info.width &&
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           top <= info.height &&
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           format == info.internal_format &&
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           type == info.type;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::GetLevelSize(
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLint target, GLint level, GLsizei* width, GLsizei* height) const {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(width);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(height);
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t face_index = GLTargetToFaceIndex(target);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level >= 0 && face_index < level_infos_.size() &&
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<size_t>(level) < level_infos_[face_index].size()) {
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level];
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info.target != 0) {
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *width = info.width;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *height = info.height;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::GetLevelType(
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLint target, GLint level, GLenum* type, GLenum* internal_format) const {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(internal_format);
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t face_index = GLTargetToFaceIndex(target);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level >= 0 && face_index < level_infos_.size() &&
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<size_t>(level) < level_infos_[face_index].size()) {
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level];
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info.target != 0) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *type = info.type;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *internal_format = info.internal_format;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GLenum Texture::SetParameter(
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FeatureInfo* feature_info, GLenum pname, GLint param) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(feature_info);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (target_ == GL_TEXTURE_EXTERNAL_OES ||
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target_ == GL_TEXTURE_RECTANGLE_ARB) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pname == GL_TEXTURE_MIN_FILTER &&
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (param != GL_NEAREST && param != GL_LINEAR))
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GL_INVALID_ENUM;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((pname == GL_TEXTURE_WRAP_S || pname == GL_TEXTURE_WRAP_T) &&
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        param != GL_CLAMP_TO_EDGE)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GL_INVALID_ENUM;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (pname) {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_MIN_FILTER:
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!feature_info->validators()->texture_min_filter_mode.IsValid(param)) {
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_ENUM;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      min_filter_ = param;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_MAG_FILTER:
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!feature_info->validators()->texture_mag_filter_mode.IsValid(param)) {
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_ENUM;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mag_filter_ = param;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case GL_TEXTURE_POOL_CHROMIUM:
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!feature_info->validators()->texture_pool.IsValid(param)) {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_ENUM;
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
60990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetMemTracker()->TrackMemFree(estimated_size());
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pool_ = param;
61190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetMemTracker()->TrackMemAlloc(estimated_size());
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_WRAP_S:
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_ENUM;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrap_s_ = param;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_WRAP_T:
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!feature_info->validators()->texture_wrap_mode.IsValid(param)) {
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_ENUM;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wrap_t_ = param;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (param < 1) {
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_VALUE;
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case GL_TEXTURE_USAGE_ANGLE:
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!feature_info->validators()->texture_usage.IsValid(param)) {
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return GL_INVALID_ENUM;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      usage_ = param;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return GL_INVALID_ENUM;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Update(feature_info);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCleared();
64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateCanRenderCondition();
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GL_NO_ERROR;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Texture::Update(const FeatureInfo* feature_info) {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update npot status.
64890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Assume GL_TEXTURE_EXTERNAL_OES textures are npot, all others
64990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  npot_ = target_ == GL_TEXTURE_EXTERNAL_OES;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level_infos_.empty()) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_complete_ = false;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cube_complete_ = false;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks that the first mip of any face is npot.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Texture::LevelInfo& info = level_infos_[ii][0];
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GLES2Util::IsNPOT(info.width) ||
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GLES2Util::IsNPOT(info.height) ||
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GLES2Util::IsNPOT(info.depth)) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      npot_ = true;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update texture_complete and cube_complete status.
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Texture::LevelInfo& first_face = level_infos_[0][0];
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int levels_needed = TextureManager::ComputeMipMapCount(
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_face.width, first_face.height, first_face.depth);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  texture_complete_ =
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cube_complete_ = (level_infos_.size() == 6) &&
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   (first_face.width == first_face.height);
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (first_face.width == 0 || first_face.height == 0) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_complete_ = false;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (first_face.type == GL_FLOAT &&
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !feature_info->feature_flags().enable_texture_float_linear &&
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mag_filter_ != GL_NEAREST)) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_complete_ = false;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (first_face.type == GL_HALF_FLOAT_OES &&
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             !feature_info->feature_flags().enable_texture_half_float_linear &&
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             (min_filter_ != GL_NEAREST_MIPMAP_NEAREST ||
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              mag_filter_ != GL_NEAREST)) {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    texture_complete_ = false;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ii < level_infos_.size() && (cube_complete_ || texture_complete_);
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++ii) {
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Texture::LevelInfo& level0 = level_infos_[ii][0];
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (level0.target == 0 ||
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        level0.width != first_face.width ||
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        level0.height != first_face.height ||
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        level0.depth != 1 ||
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        level0.internal_format != first_face.internal_format ||
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        level0.format != first_face.format ||
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        level0.type != first_face.type) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cube_complete_ = false;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get level0 dimensions
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei width = level0.width;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei height = level0.height;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei depth = level0.depth;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (GLint jj = 1; jj < levels_needed; ++jj) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // compute required size for mip.
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      width = std::max(1, width >> 1);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      height = std::max(1, height >> 1);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      depth = std::max(1, depth >> 1);
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const Texture::LevelInfo& info = level_infos_[ii][jj];
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (info.target == 0 ||
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info.width != width ||
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info.height != height ||
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info.depth != depth ||
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info.internal_format != level0.internal_format ||
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info.format != level0.format ||
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          info.type != level0.type) {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        texture_complete_ = false;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(decoder);
73090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (cleared_) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Texture::LevelInfo& first_face = level_infos_[0][0];
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int levels_needed = TextureManager::ComputeMipMapCount(
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_face.width, first_face.height, first_face.depth);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < level_infos_.size(); ++ii) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (GLint jj = 0; jj < levels_needed; ++jj) {
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Texture::LevelInfo& info = level_infos_[ii][jj];
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (info.target != 0) {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ClearLevel(decoder, info.target, jj)) {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return false;
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
74890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateSafeToRenderFrom(true);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::IsLevelCleared(GLenum target, GLint level) const {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t face_index = GLTargetToFaceIndex(target);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (face_index >= level_infos_.size() ||
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level >= static_cast<GLint>(level_infos_[face_index].size())) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Texture::LevelInfo& info = level_infos_[face_index][level];
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info.cleared;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Texture::ClearLevel(
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLES2Decoder* decoder, GLenum target, GLint level) {
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(decoder);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t face_index = GLTargetToFaceIndex(target);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (face_index >= level_infos_.size() ||
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level >= static_cast<GLint>(level_infos_[face_index].size())) {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Texture::LevelInfo& info = level_infos_[face_index][level];
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(target == info.target);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (info.target == 0 ||
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.cleared ||
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.width == 0 ||
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.height == 0 ||
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.depth == 0) {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: It seems kind of gross to call back into the decoder for this
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // but only the decoder knows all the state (like unpack_alignment_) that's
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // needed to be able to call GL correctly.
78890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  bool cleared = decoder->ClearLevel(
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service_id_, target_, info.target, info.level, info.format, info.type,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.width, info.height, immutable_);
79190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateMipCleared(&info, cleared);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info.cleared;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Texture::SetLevelImage(
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FeatureInfo* feature_info,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target,
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GLImage* image) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(level, 0);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_.size());
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LT(static_cast<size_t>(level),
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            level_infos_[GLTargetToFaceIndex(target)].size());
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Texture::LevelInfo& info =
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      level_infos_[GLTargetToFaceIndex(target)][level];
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(info.target, target);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(info.level, level);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  info.image = image;
81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  UpdateCanRenderCondition();
811294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  UpdateHasImages();
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
814294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.orggfx::GLImage* Texture::GetLevelImage(GLint target, GLint level) const {
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t face_index = GLTargetToFaceIndex(target);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (level >= 0 && face_index < level_infos_.size() &&
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<size_t>(level) < level_infos_[face_index].size()) {
8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const LevelInfo& info = level_infos_[GLTargetToFaceIndex(target)][level];
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info.target != 0) {
820868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return info.image.get();
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TextureRef::TextureRef(TextureManager* manager,
828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       GLuint client_id,
829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                       Texture* texture)
83090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    : manager_(manager),
831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      texture_(texture),
832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      client_id_(client_id),
833eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      is_stream_texture_owner_(false) {
83490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(manager_);
83590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(texture_);
83690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture_->AddTextureRef(this);
83790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  manager_->StartTracking(this);
83890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
83990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_refptr<TextureRef> TextureRef::Create(TextureManager* manager,
841868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                             GLuint client_id,
84290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                             GLuint service_id) {
843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return new TextureRef(manager, client_id, new Texture(service_id));
84490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
84690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TextureRef::~TextureRef() {
84790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  manager_->StopTracking(this);
84890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture_->RemoveTextureRef(this, manager_->have_context_);
84990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  manager_ = NULL;
85090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
85190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextureManager::TextureManager(
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MemoryTracker* memory_tracker,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FeatureInfo* feature_info,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint max_texture_size,
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint max_cube_map_texture_size)
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : memory_tracker_managed_(
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)),
8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memory_tracker_unmanaged_(
8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)),
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      feature_info_(feature_info),
86290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      framebuffer_manager_(NULL),
863eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      stream_texture_manager_(NULL),
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_texture_size_(max_texture_size),
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_cube_map_texture_size_(max_cube_map_texture_size),
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_levels_(ComputeMipMapCount(max_texture_size,
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     max_texture_size,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     max_texture_size)),
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size,
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              max_cube_map_texture_size,
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              max_cube_map_texture_size)),
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_unrenderable_textures_(0),
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_unsafe_textures_(0),
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_uncleared_mips_(0),
875294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org      num_images_(0),
8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texture_count_(0),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      have_context_(true) {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int ii = 0; ii < kNumDefaultTextures; ++ii) {
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    black_texture_ids_[ii] = 0;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureManager::Initialize() {
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gman): The default textures have to be real textures, not the 0
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // texture because we simulate non shared resources on top of shared
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // resources and all contexts that share resource share the same default
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // texture.
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_textures_[kTexture2D] = CreateDefaultAndBlackTextures(
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_TEXTURE_2D, &black_texture_ids_[kTexture2D]);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  default_textures_[kCubeMap] = CreateDefaultAndBlackTextures(
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GL_TEXTURE_CUBE_MAP, &black_texture_ids_[kCubeMap]);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (feature_info_->feature_flags().oes_egl_image_external) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_textures_[kExternalOES] = CreateDefaultAndBlackTextures(
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GL_TEXTURE_EXTERNAL_OES, &black_texture_ids_[kExternalOES]);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (feature_info_->feature_flags().arb_texture_rectangle) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default_textures_[kRectangleARB] = CreateDefaultAndBlackTextures(
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GL_TEXTURE_RECTANGLE_ARB, &black_texture_ids_[kRectangleARB]);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_refptr<TextureRef>
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TextureManager::CreateDefaultAndBlackTextures(
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GLenum target,
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GLuint* black_texture) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static uint8 black[] = {0, 0, 0, 255};
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sampling a texture not associated with any EGLImage sibling will return
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // black values according to the spec.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES);
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool needs_faces = (target == GL_TEXTURE_CUBE_MAP);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make default textures and texture for replacing non-renderable textures.
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint ids[2];
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glGenTextures(arraysize(ids), ids);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned long ii = 0; ii < arraysize(ids); ++ii) {
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    glBindTexture(target, ids[ii]);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (needs_initialization) {
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (needs_faces) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (int jj = 0; jj < GLES2Util::kNumFaces; ++jj) {
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          glTexImage2D(GLES2Util::IndexToGLFaceTarget(jj), 0, GL_RGBA, 1, 1, 0,
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       GL_RGBA, GL_UNSIGNED_BYTE, black);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        glTexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     GL_UNSIGNED_BYTE, black);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  glBindTexture(target, 0);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<TextureRef> default_texture(
937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      TextureRef::Create(this, 0, ids[1]));
938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SetTarget(default_texture.get(), target);
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (needs_faces) {
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) {
941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetLevelInfo(default_texture.get(),
942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GLES2Util::IndexToGLFaceTarget(ii),
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   0,
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_RGBA,
945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   0,
949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_RGBA,
950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_UNSIGNED_BYTE,
951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   true);
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (needs_initialization) {
955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetLevelInfo(default_texture.get(),
956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_TEXTURE_2D,
957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   0,
958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_RGBA,
959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   0,
963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_RGBA,
964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_UNSIGNED_BYTE,
965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   true);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      SetLevelInfo(default_texture.get(),
968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_TEXTURE_EXTERNAL_OES,
969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   0,
970868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_RGBA,
971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   1,
974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   0,
975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_RGBA,
976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   GL_UNSIGNED_BYTE,
977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                   true);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *black_texture = ids[0];
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return default_texture;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureManager::ValidForTarget(
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target, GLint level, GLsizei width, GLsizei height, GLsizei depth) {
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLsizei max_size = MaxSizeForTarget(target) >> level;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return level >= 0 &&
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         width >= 0 &&
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         height >= 0 &&
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         depth >= 0 &&
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         level < MaxLevelsForTarget(target) &&
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         width <= max_size &&
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         height <= max_size &&
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         depth <= max_size &&
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (level == 0 || feature_info_->feature_flags().npot_ok ||
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (!GLES2Util::IsNPOT(width) &&
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           !GLES2Util::IsNPOT(height) &&
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           !GLES2Util::IsNPOT(depth))) &&
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) &&
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         (target != GL_TEXTURE_2D || (depth == 1));
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::SetTarget(TextureRef* ref, GLenum target) {
100590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
1006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ref->texture()
1007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ->SetTarget(feature_info_.get(), target, MaxLevelsForTarget(target));
100890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
100990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
101090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::SetStreamTexture(TextureRef* ref, bool stream_texture) {
101190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
1012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Only the owner can mark as non-stream texture.
1013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_EQ(stream_texture, !ref->is_stream_texture_owner_);
101490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ref->texture()->SetStreamTexture(stream_texture);
1015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ref->set_is_stream_texture_owner(stream_texture);
1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool TextureManager::IsStreamTextureOwner(TextureRef* ref) {
1019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(ref);
1020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return ref->is_stream_texture_owner();
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::SetLevelCleared(TextureRef* ref,
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     GLenum target,
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     GLint level,
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     bool cleared) {
102790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
102890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ref->texture()->SetLevelCleared(target, level, cleared);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureManager::ClearRenderableLevels(
103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GLES2Decoder* decoder, TextureRef* ref) {
103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
103490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ref->texture()->ClearRenderableLevels(decoder);
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextureManager::ClearTextureLevel(
103890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    GLES2Decoder* decoder, TextureRef* ref,
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target, GLint level) {
104090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
104190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Texture* texture = ref->texture();
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (texture->num_uncleared_mips() == 0) {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = texture->ClearLevel(decoder, target, level);
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture->UpdateCleared();
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureManager::SetLevelInfo(
105190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TextureRef* ref,
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target,
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum internal_format,
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei width,
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei height,
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei depth,
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint border,
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum format,
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum type,
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool cleared) {
106290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
106390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Texture* texture = ref->texture();
10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
106590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  texture->SetLevelInfo(feature_info_.get(),
1067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        target,
1068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        level,
1069868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        internal_format,
1070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        width,
1071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        height,
1072868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        depth,
1073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        border,
1074868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        format,
1075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        type,
1076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        cleared);
107790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Texture* TextureManager::Produce(TextureRef* ref) {
108190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
1082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ref->texture();
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TextureRef* TextureManager::Consume(
1086868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    GLuint client_id,
1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Texture* texture) {
1088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(client_id);
1089868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<TextureRef> ref(new TextureRef(this, client_id, texture));
1090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool result = textures_.insert(std::make_pair(client_id, ref)).second;
1091868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(result);
1092868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ref.get();
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureManager::SetParameter(
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* function_name, ErrorState* error_state,
109790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TextureRef* ref, GLenum pname, GLint param) {
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(error_state);
109990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
110090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Texture* texture = ref->texture();
1101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  GLenum result = texture->SetParameter(feature_info_.get(), pname, param);
11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (result != GL_NO_ERROR) {
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (result == GL_INVALID_ENUM) {
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          error_state, function_name, param, "param");
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          error_state, result, function_name, pname, static_cast<GLint>(param));
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Texture tracking pools exist only for the command decoder, so
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // do not pass them on to the native GL implementation.
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pname != GL_TEXTURE_POOL_CHROMIUM) {
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      glTexParameteri(texture->target(), pname, param);
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool TextureManager::MarkMipmapsGenerated(TextureRef* ref) {
112090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
112190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Texture* texture = ref->texture();
112290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture->GetMemTracker()->TrackMemFree(texture->estimated_size());
1123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool result = texture->MarkMipmapsGenerated(feature_info_.get());
112490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  texture->GetMemTracker()->TrackMemAlloc(texture->estimated_size());
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TextureRef* TextureManager::CreateTexture(
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint client_id, GLuint service_id) {
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(0u, service_id);
1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<TextureRef> ref(TextureRef::Create(
1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      this, client_id, service_id));
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::pair<TextureMap::iterator, bool> result =
113490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      textures_.insert(std::make_pair(client_id, ref));
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(result.second);
113690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ref.get();
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TextureRef* TextureManager::GetTexture(
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLuint client_id) const {
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TextureMap::const_iterator it = textures_.find(client_id);
1142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return it != textures_.end() ? it->second.get() : NULL;
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TextureManager::RemoveTexture(GLuint client_id) {
11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TextureMap::iterator it = textures_.find(client_id);
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it != textures_.end()) {
1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    it->second->reset_client_id();
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    textures_.erase(it);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::StartTracking(TextureRef* ref) {
115490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Texture* texture = ref->texture();
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ++texture_count_;
115690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  num_uncleared_mips_ += texture->num_uncleared_mips();
115790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!texture->SafeToRenderFrom())
115890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++num_unsafe_textures_;
1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!texture->CanRender(feature_info_.get()))
116090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++num_unrenderable_textures_;
1161294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  if (texture->HasImages())
1162294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    ++num_images_;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::StopTracking(TextureRef* ref) {
1166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  FOR_EACH_OBSERVER(DestructionObserver,
1167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    destruction_observers_,
1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    OnTextureRefDestroying(ref));
1169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
117090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  Texture* texture = ref->texture();
1171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (ref->is_stream_texture_owner_ && stream_texture_manager_) {
1172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DCHECK(texture->IsStreamTexture());
1173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    stream_texture_manager_->DestroyStreamTexture(texture->service_id());
1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  --texture_count_;
1177294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  if (texture->HasImages()) {
1178294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    DCHECK_NE(0, num_images_);
1179294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org    --num_images_;
1180294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  }
1181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!texture->CanRender(feature_info_.get())) {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(0, num_unrenderable_textures_);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --num_unrenderable_textures_;
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!texture->SafeToRenderFrom()) {
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_NE(0, num_unsafe_textures_);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    --num_unsafe_textures_;
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  num_uncleared_mips_ -= texture->num_uncleared_mips();
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(num_uncleared_mips_, 0);
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MemoryTypeTracker* TextureManager::GetMemTracker(GLenum tracking_pool) {
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch(tracking_pool) {
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case GL_TEXTURE_POOL_MANAGED_CHROMIUM:
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return memory_tracker_managed_.get();
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case GL_TEXTURE_POOL_UNMANAGED_CHROMIUM:
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return memory_tracker_unmanaged_.get();
12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Texture* TextureManager::GetTextureForServiceId(GLuint service_id) const {
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This doesn't need to be fast. It's only used during slow queries.
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (TextureMap::const_iterator it = textures_.begin();
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != textures_.end(); ++it) {
1212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Texture* texture = it->second->texture();
1213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (texture->service_id() == service_id)
1214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return texture;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return NULL;
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLsizei TextureManager::ComputeMipMapCount(
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLsizei width, GLsizei height, GLsizei depth) {
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureManager::SetLevelImage(
122590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TextureRef* ref,
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target,
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GLImage* image) {
122990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ref);
1230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ref->texture()->SetLevelImage(feature_info_.get(), target, level, image);
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextureManager::AddToSignature(
123490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    TextureRef* ref,
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target,
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint level,
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* signature) const {
123890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ref->texture()->AddToSignature(feature_info_.get(), target, level, signature);
123990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
124090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
124190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::UpdateSafeToRenderFrom(int delta) {
124290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  num_unsafe_textures_ += delta;
124390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_GE(num_unsafe_textures_, 0);
124490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
124590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
124690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::UpdateUnclearedMips(int delta) {
124790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  num_uncleared_mips_ += delta;
124890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK_GE(num_uncleared_mips_, 0);
124990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
125090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
125190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::UpdateCanRenderCondition(
125290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Texture::CanRenderCondition old_condition,
125390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    Texture::CanRenderCondition new_condition) {
125490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (old_condition == Texture::CAN_RENDER_NEVER ||
125590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (old_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
125690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       !feature_info_->feature_flags().npot_ok)) {
125790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DCHECK_GT(num_unrenderable_textures_, 0);
125890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    --num_unrenderable_textures_;
125990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
126090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (new_condition == Texture::CAN_RENDER_NEVER ||
126190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      (new_condition == Texture::CAN_RENDER_ONLY_IF_NPOT &&
126290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)       !feature_info_->feature_flags().npot_ok))
126390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ++num_unrenderable_textures_;
126490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
126590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1266294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.orgvoid TextureManager::UpdateNumImages(int delta) {
1267294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  num_images_ += delta;
1268294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org  DCHECK_GE(num_images_, 0);
1269294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org}
1270294545aa54ddff00ccb2f1188f231ff0ebbd9386reveman@chromium.org
127190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TextureManager::IncFramebufferStateChangeCount() {
127290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (framebuffer_manager_)
127390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    framebuffer_manager_->IncFramebufferStateChangeCount();
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
1278