12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/resource_provider.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <algorithm>
8a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include <limits>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/debug/trace_event.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "cc/base/util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/gl_renderer.h"  // For the GLC() macro.
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/platform_color.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/resources/returned_resource.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "cc/resources/shared_bitmap_manager.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "cc/resources/texture_uploader.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/resources/transferable_resource.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2ext.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/skia/include/core/SkSurface.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/skia/include/gpu/GrContext.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/skia/include/gpu/SkGpuDevice.h"
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/gfx/frame_time.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/rect.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/vector2d.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using gpu::gles2::GLES2Interface;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class IdAllocator {
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~IdAllocator() {}
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual GLuint NextId() = 0;
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  IdAllocator(GLES2Interface* gl, size_t id_allocation_chunk_size)
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : gl_(gl),
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        id_allocation_chunk_size_(id_allocation_chunk_size),
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ids_(new GLuint[id_allocation_chunk_size]),
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        next_id_index_(id_allocation_chunk_size) {
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(id_allocation_chunk_size_);
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl_;
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const size_t id_allocation_chunk_size_;
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<GLuint[]> ids_;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  size_t next_id_index_;
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace {
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Measured in seconds.
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const double kSoftwareUploadTickRate = 0.000250;
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const double kTextureUploadTickRate = 0.004;
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)GLenum TextureToStorageFormat(ResourceFormat format) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLenum storage_format = GL_RGBA8_OES;
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  switch (format) {
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    case RGBA_8888:
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    case BGRA_8888:
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      storage_format = GL_BGRA8_EXT;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case RGBA_4444:
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case LUMINANCE_8:
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case RGB_565:
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case ETC1:
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      NOTREACHED();
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return storage_format;
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool IsFormatSupportedForStorage(ResourceFormat format) {
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  switch (format) {
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    case RGBA_8888:
86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    case BGRA_8888:
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return true;
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    case RGBA_4444:
89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    case LUMINANCE_8:
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case RGB_565:
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case ETC1:
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      return false;
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return false;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GrPixelConfig ToGrPixelConfig(ResourceFormat format) {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (format) {
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RGBA_8888:
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return kRGBA_8888_GrPixelConfig;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case BGRA_8888:
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return kBGRA_8888_GrPixelConfig;
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RGBA_4444:
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return kRGBA_4444_GrPixelConfig;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(false) << "Unsupported resource format.";
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return kSkia8888_GrPixelConfig;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
112f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)void CopyBitmap(const SkBitmap& src, uint8_t* dst, SkColorType dst_color_type) {
113f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  SkImageInfo dst_info = src.info();
114f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  dst_info.fColorType = dst_color_type;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
116f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  // bitmap data. There will be no need to call SkAlign4 once crbug.com/293728
117f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  // is fixed.
118f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  const size_t dst_row_bytes = SkAlign4(dst_info.minRowBytes());
119f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  CHECK_EQ(0u, dst_row_bytes % 4);
120f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  bool success = src.readPixels(dst_info, dst, dst_row_bytes, 0, 0);
121f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  CHECK_EQ(true, success);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class ScopedSetActiveTexture {
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : gl_(gl), unit_(unit) {
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (unit_ != GL_TEXTURE0)
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->ActiveTexture(unit_));
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ~ScopedSetActiveTexture() {
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Active unit being GL_TEXTURE0 is effectively the ground state.
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (unit_ != GL_TEXTURE0)
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl_;
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GLenum unit_;
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class TextureIdAllocator : public IdAllocator {
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TextureIdAllocator(GLES2Interface* gl,
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                     size_t texture_id_allocation_chunk_size)
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : IdAllocator(gl, texture_id_allocation_chunk_size) {}
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~TextureIdAllocator() {
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->DeleteTextures(id_allocation_chunk_size_ - next_id_index_,
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        ids_.get() + next_id_index_);
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Overridden from IdAllocator:
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual GLuint NextId() OVERRIDE {
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (next_id_index_ == id_allocation_chunk_size_) {
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->GenTextures(id_allocation_chunk_size_, ids_.get());
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      next_id_index_ = 0;
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return ids_[next_id_index_++];
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TextureIdAllocator);
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class BufferIdAllocator : public IdAllocator {
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  BufferIdAllocator(GLES2Interface* gl, size_t buffer_id_allocation_chunk_size)
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      : IdAllocator(gl, buffer_id_allocation_chunk_size) {}
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~BufferIdAllocator() {
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl_->DeleteBuffers(id_allocation_chunk_size_ - next_id_index_,
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                       ids_.get() + next_id_index_);
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Overridden from IdAllocator:
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual GLuint NextId() OVERRIDE {
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (next_id_index_ == id_allocation_chunk_size_) {
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl_->GenBuffers(id_allocation_chunk_size_, ids_.get());
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      next_id_index_ = 0;
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return ids_[next_id_index_++];
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator);
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Generic fence implementation for query objects. Fence has passed when query
193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// result is available.
194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass QueryFence : public ResourceProvider::Fence {
195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public:
196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  QueryFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : gl_(gl), query_id_(query_id) {}
198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
199a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Overridden from ResourceProvider::Fence:
200a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual bool HasPassed() OVERRIDE {
201a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    unsigned available = 1;
202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gl_->GetQueryObjectuivEXT(
203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
204a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return !!available;
205a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
206a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
207a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private:
208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual ~QueryFence() {}
209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gpu::gles2::GLES2Interface* gl_;
211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  unsigned query_id_;
212a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(QueryFence);
214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch};
215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::Resource::Resource()
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : child_id(0),
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      gl_id(0),
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_pixel_buffer_id(0),
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_upload_query_id(0),
223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gl_read_lock_query_id(0),
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pixels(NULL),
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      lock_for_read_count(0),
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      imported_count(0),
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      exported_count(0),
228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      dirty_image(false),
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      locked_for_write(false),
230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      lost(false),
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      marked_for_deletion(false),
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_set_pixels(false),
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      set_pixels_completion_forced(false),
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      allocated(false),
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enable_read_lock_fences(false),
236effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      has_shared_bitmap_id(false),
237effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      allow_overlay(false),
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      read_lock_fence(NULL),
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size(),
240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      origin(Internal),
24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      target(0),
242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      original_filter(0),
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      filter(0),
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      image_id(0),
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      bound_image_id(0),
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      texture_pool(0),
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      wrap_mode(0),
248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      hint(TextureUsageAny),
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      type(InvalidType),
2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      format(RGBA_8888),
2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      shared_bitmap(NULL) {}
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::Resource::~Resource() {}
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ResourceProvider::Resource::Resource(GLuint texture_id,
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const gfx::Size& size,
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     Origin origin,
25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     GLenum target,
25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     GLenum filter,
26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     GLenum texture_pool,
26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     GLint wrap_mode,
26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     TextureUsageHint hint,
26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     ResourceFormat format)
26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : child_id(0),
26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      gl_id(texture_id),
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_pixel_buffer_id(0),
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_upload_query_id(0),
268a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gl_read_lock_query_id(0),
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pixels(NULL),
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      lock_for_read_count(0),
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      imported_count(0),
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      exported_count(0),
273effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      dirty_image(false),
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      locked_for_write(false),
275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      lost(false),
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      marked_for_deletion(false),
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_set_pixels(false),
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      set_pixels_completion_forced(false),
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      allocated(false),
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enable_read_lock_fences(false),
281effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      has_shared_bitmap_id(false),
282effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      allow_overlay(false),
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      read_lock_fence(NULL),
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size(size),
285effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      origin(origin),
28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      target(target),
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      original_filter(filter),
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      filter(filter),
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      image_id(0),
2908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      bound_image_id(0),
291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      texture_pool(texture_pool),
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      wrap_mode(wrap_mode),
293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      hint(hint),
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      type(GLTexture),
2951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      format(format),
2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      shared_bitmap(NULL) {
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(origin == Internal, !!texture_pool);
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ResourceProvider::Resource::Resource(uint8_t* pixels,
3021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                     SharedBitmap* bitmap,
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const gfx::Size& size,
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     Origin origin,
30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     GLenum filter,
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                     GLint wrap_mode)
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : child_id(0),
30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      gl_id(0),
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_pixel_buffer_id(0),
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gl_upload_query_id(0),
311a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gl_read_lock_query_id(0),
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pixels(pixels),
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      lock_for_read_count(0),
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      imported_count(0),
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      exported_count(0),
316effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      dirty_image(false),
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      locked_for_write(false),
318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      lost(false),
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      marked_for_deletion(false),
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      pending_set_pixels(false),
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      set_pixels_completion_forced(false),
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      allocated(false),
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      enable_read_lock_fences(false),
324effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      has_shared_bitmap_id(!!bitmap),
325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      allow_overlay(false),
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      read_lock_fence(NULL),
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size(size),
328effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      origin(origin),
32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      target(0),
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      original_filter(filter),
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      filter(filter),
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      image_id(0),
3338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      bound_image_id(0),
334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      texture_pool(0),
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      wrap_mode(wrap_mode),
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      hint(TextureUsageAny),
337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      type(Bitmap),
3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      format(RGBA_8888),
3391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      shared_bitmap(bitmap) {
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(origin == Delegated || pixels);
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (bitmap)
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    shared_bitmap_id = bitmap->id();
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     const gfx::Size& size,
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     Origin origin,
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     GLenum filter,
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     GLint wrap_mode)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : child_id(0),
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gl_id(0),
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gl_pixel_buffer_id(0),
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gl_upload_query_id(0),
355a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gl_read_lock_query_id(0),
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pixels(NULL),
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      lock_for_read_count(0),
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      imported_count(0),
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      exported_count(0),
360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      dirty_image(false),
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      locked_for_write(false),
362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      lost(false),
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      marked_for_deletion(false),
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pending_set_pixels(false),
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      set_pixels_completion_forced(false),
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      allocated(false),
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      enable_read_lock_fences(false),
368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      has_shared_bitmap_id(true),
369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      allow_overlay(false),
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      read_lock_fence(NULL),
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      size(size),
372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      origin(origin),
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      target(0),
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      original_filter(filter),
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      filter(filter),
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      image_id(0),
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bound_image_id(0),
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      texture_pool(0),
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      wrap_mode(wrap_mode),
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      hint(TextureUsageAny),
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      type(Bitmap),
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      format(RGBA_8888),
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shared_bitmap_id(bitmap_id),
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shared_bitmap(NULL) {
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::RasterBuffer::RasterBuffer(
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Resource* resource,
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider* resource_provider)
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : resource_(resource),
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource_provider_(resource_provider),
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      locked_canvas_(NULL),
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      canvas_save_count_(0) {
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource_);
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource_provider_);
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::RasterBuffer::~RasterBuffer() {}
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* ResourceProvider::RasterBuffer::LockForWrite() {
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::RasterBuffer::LockForWrite");
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!locked_canvas_);
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  locked_canvas_ = DoLockForWrite();
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  canvas_save_count_ = locked_canvas_ ? locked_canvas_->save() : 0;
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return locked_canvas_;
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
412a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ResourceProvider::RasterBuffer::UnlockForWrite() {
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::RasterBuffer::UnlockForWrite");
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (locked_canvas_) {
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    locked_canvas_->restoreToCount(canvas_save_count_);
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    locked_canvas_ = NULL;
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return DoUnlockForWrite();
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::DirectRasterBuffer::DirectRasterBuffer(
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Resource* resource,
425010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ResourceProvider* resource_provider,
426010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool use_distance_field_text )
427010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    : RasterBuffer(resource, resource_provider),
428010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      surface_generation_id_(0u),
429010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      use_distance_field_text_(use_distance_field_text) {}
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::DirectRasterBuffer::~DirectRasterBuffer() {}
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* ResourceProvider::DirectRasterBuffer::DoLockForWrite() {
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!surface_)
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    surface_ = CreateSurface();
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  surface_generation_id_ = surface_ ? surface_->generationID() : 0u;
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return surface_ ? surface_->getCanvas() : NULL;
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ResourceProvider::DirectRasterBuffer::DoUnlockForWrite() {
441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // generationID returns a non-zero, unique value corresponding to the content
442a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // of surface. Hence, a change since DoLockForWrite was called means the
443a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // surface has changed.
444a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return surface_ ? surface_generation_id_ != surface_->generationID() : false;
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)skia::RefPtr<SkSurface> ResourceProvider::DirectRasterBuffer::CreateSurface() {
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  skia::RefPtr<SkSurface> surface;
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (resource()->type) {
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case GLTexture: {
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(resource()->gl_id);
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      class GrContext* gr_context = resource_provider()->GrContext();
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (gr_context) {
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        GrBackendTextureDesc desc;
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        desc.fFlags = kRenderTarget_GrBackendTextureFlag;
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        desc.fWidth = resource()->size.width();
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        desc.fHeight = resource()->size.height();
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        desc.fConfig = ToGrPixelConfig(resource()->format);
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        desc.fTextureHandle = resource()->gl_id;
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        skia::RefPtr<GrTexture> gr_texture =
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            skia::AdoptRef(gr_context->wrapBackendTexture(desc));
463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        SkSurface::TextRenderMode text_render_mode =
464010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            use_distance_field_text_ ? SkSurface::kDistanceField_TextRenderMode
465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                     : SkSurface::kStandard_TextRenderMode;
466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        surface = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            gr_texture->asRenderTarget(), text_render_mode));
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case Bitmap: {
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(resource()->pixels);
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK_EQ(RGBA_8888, resource()->format);
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      SkImageInfo image_info = SkImageInfo::MakeN32Premul(
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          resource()->size.width(), resource()->size.height());
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      surface = skia::AdoptRef(SkSurface::NewRasterDirect(
477effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          image_info, resource()->pixels, image_info.minRowBytes()));
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return surface;
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::BitmapRasterBuffer::BitmapRasterBuffer(
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Resource* resource,
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider* resource_provider)
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : RasterBuffer(resource, resource_provider),
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      mapped_buffer_(NULL),
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      raster_bitmap_generation_id_(0u) {}
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::BitmapRasterBuffer::~BitmapRasterBuffer() {}
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* ResourceProvider::BitmapRasterBuffer::DoLockForWrite() {
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!mapped_buffer_);
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!raster_canvas_);
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int stride = 0;
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  mapped_buffer_ = MapBuffer(&stride);
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!mapped_buffer_)
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (resource()->format) {
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RGBA_4444:
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Use the default stride if we will eventually convert this
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // bitmap to 4444.
508effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      raster_bitmap_.allocN32Pixels(resource()->size.width(),
509effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                    resource()->size.height());
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RGBA_8888:
512effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case BGRA_8888: {
513effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      SkImageInfo info = SkImageInfo::MakeN32Premul(resource()->size.width(),
514effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                    resource()->size.height());
515effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (0 == stride)
516effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        stride = info.minRowBytes();
517effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      raster_bitmap_.installPixels(info, mapped_buffer_, stride);
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
519effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case LUMINANCE_8:
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case RGB_565:
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case ETC1:
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      NOTREACHED();
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  raster_canvas_ = skia::AdoptRef(new SkCanvas(raster_bitmap_));
527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  raster_bitmap_generation_id_ = raster_bitmap_.getGenerationID();
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return raster_canvas_.get();
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ResourceProvider::BitmapRasterBuffer::DoUnlockForWrite() {
5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  raster_canvas_.clear();
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // getGenerationID returns a non-zero, unique value corresponding to the
535a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pixels in bitmap. Hence, a change since DoLockForWrite was called means the
536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // bitmap has changed.
537a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool raster_bitmap_changed =
538a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      raster_bitmap_generation_id_ != raster_bitmap_.getGenerationID();
539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
540a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (raster_bitmap_changed) {
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SkColorType buffer_colorType =
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ResourceFormatToSkColorType(resource()->format);
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (mapped_buffer_ && (buffer_colorType != raster_bitmap_.colorType()))
544a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      CopyBitmap(raster_bitmap_, mapped_buffer_, buffer_colorType);
545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  raster_bitmap_.reset();
5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UnmapBuffer();
5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  mapped_buffer_ = NULL;
550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return raster_bitmap_changed;
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::ImageRasterBuffer::ImageRasterBuffer(
5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Resource* resource,
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider* resource_provider)
5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BitmapRasterBuffer(resource, resource_provider) {}
5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::ImageRasterBuffer::~ImageRasterBuffer() {}
5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint8_t* ResourceProvider::ImageRasterBuffer::MapBuffer(int* stride) {
5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return resource_provider()->MapImage(resource(), stride);
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::ImageRasterBuffer::UnmapBuffer() {
5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource_provider()->UnmapImage(resource());
5665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::PixelRasterBuffer::PixelRasterBuffer(
5695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Resource* resource,
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceProvider* resource_provider)
5715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BitmapRasterBuffer(resource, resource_provider) {}
5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ResourceProvider::PixelRasterBuffer::~PixelRasterBuffer() {}
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint8_t* ResourceProvider::PixelRasterBuffer::MapBuffer(int* stride) {
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return resource_provider()->MapPixelBuffer(resource(), stride);
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::PixelRasterBuffer::UnmapBuffer() {
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource_provider()->UnmapPixelBuffer(resource());
58158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ResourceProvider::Child::Child() : marked_for_deletion(false) {}
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::Child::~Child() {}
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceProvider> ResourceProvider::Create(
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OutputSurface* output_surface,
5891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SharedBitmapManager* shared_bitmap_manager,
590d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int highp_threshold_min,
5910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    bool use_rgba_4444_texture_format,
592010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    size_t id_allocation_chunk_size,
593010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    bool use_distance_field_text) {
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider(
595d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      new ResourceProvider(output_surface,
5961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                           shared_bitmap_manager,
597d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                           highp_threshold_min,
5980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                           use_rgba_4444_texture_format,
599010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           id_allocation_chunk_size,
600010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                           use_distance_field_text));
6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (resource_provider->ContextGL())
6030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    resource_provider->InitializeGL();
6040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  else
6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    resource_provider->InitializeSoftware();
6067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_NE(InvalidType, resource_provider->default_resource_type());
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return resource_provider.Pass();
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::~ResourceProvider() {
61268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  while (!children_.empty())
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DestroyChildInternal(children_.begin(), ForShutdown);
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!resources_.empty())
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DeleteResourceInternal(resources_.begin(), ForShutdown);
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CleanUpGLIfNeeded();
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceProvider::InUseByConsumer(ResourceId id) {
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
62268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return resource->lock_for_read_count > 0 || resource->exported_count > 0 ||
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         resource->lost;
62468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
62568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool ResourceProvider::IsLost(ResourceId id) {
62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Resource* resource = GetResource(id);
62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return resource->lost;
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
63123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool ResourceProvider::AllowOverlay(ResourceId id) {
63223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Resource* resource = GetResource(id);
63323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return resource->allow_overlay;
63423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
63523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ResourceId ResourceProvider::CreateResource(
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size& size,
638d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GLint wrap_mode,
639d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureUsageHint hint,
640d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceFormat format) {
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!size.IsEmpty());
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (default_resource_type_) {
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case GLTexture:
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return CreateGLTexture(size,
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             GL_TEXTURE_2D,
646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             wrap_mode,
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             hint,
649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             format);
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Bitmap:
651d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      DCHECK_EQ(RGBA_8888, format);
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return CreateBitmap(size, wrap_mode);
6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case InvalidType:
6547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(FATAL) << "Invalid default resource type.";
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size& size,
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GLenum target,
664d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    GLint wrap_mode,
665d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureUsageHint hint,
666d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceFormat format) {
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!size.IsEmpty());
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (default_resource_type_) {
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case GLTexture:
670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return CreateGLTexture(size,
671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             target,
672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             GL_TEXTURE_POOL_MANAGED_CHROMIUM,
673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             wrap_mode,
674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             hint,
675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             format);
6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case Bitmap:
677d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      DCHECK_EQ(RGBA_8888, format);
678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return CreateBitmap(size, wrap_mode);
6797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    case InvalidType:
6807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      break;
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG(FATAL) << "Invalid default resource type.";
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return 0;
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size& size,
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GLenum target,
69058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GLenum texture_pool,
69158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GLint wrap_mode,
692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    TextureUsageHint hint,
693d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ResourceFormat format) {
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(size.width(), max_texture_size_);
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LE(size.height(), max_texture_size_);
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceId id = next_id_++;
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource resource(0,
7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    size,
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    Resource::Internal,
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    target,
7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    GL_LINEAR,
7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    texture_pool,
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    wrap_mode,
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    hint,
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    format);
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource.allocated = false;
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resources_[id] = resource;
7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return id;
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size& size, GLint wrap_mode) {
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<SharedBitmap> bitmap;
7181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (shared_bitmap_manager_)
7191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size);
7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
7211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uint8_t* pixels;
722c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (bitmap) {
7231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    pixels = bitmap->pixels();
724c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  } else {
725c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    size_t bytes = SharedBitmap::CheckedSizeInBytes(size);
726c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    pixels = new uint8_t[bytes];
727c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(pixels);
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceId id = next_id_++;
7311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Resource resource(
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      pixels, bitmap.release(), size, Resource::Internal, GL_LINEAR, wrap_mode);
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource.allocated = true;
7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resources_[id] = resource;
7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return id;
7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
738010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
739010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const gfx::Size& size,
740010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    unsigned io_surface_id) {
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceId id = next_id_++;
744010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Resource resource(0,
745d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    gfx::Size(),
746010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    Resource::Internal,
747010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    GL_TEXTURE_RECTANGLE_ARB,
748d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    GL_LINEAR,
749010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                    GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
750d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    GL_CLAMP_TO_EDGE,
751d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    TextureUsageAny,
752d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                    RGBA_8888);
753010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  LazyCreate(&resource);
754010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  GLES2Interface* gl = ContextGL();
755010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(gl);
756010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id);
757010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  gl->TexImageIOSurface2DCHROMIUM(
758010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      GL_TEXTURE_RECTANGLE_ARB, size.width(), size.height(), io_surface_id, 0);
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource.allocated = true;
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resources_[id] = resource;
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return id;
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
765d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const TextureMailbox& mailbox,
766d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<SingleReleaseCallback> release_callback) {
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Just store the information. Mailbox will be consumed in LockForRead().
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceId id = next_id_++;
770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(mailbox.IsValid());
771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Resource& resource = resources_[id];
772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (mailbox.IsTexture()) {
773d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    resource = Resource(0,
774d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        gfx::Size(),
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        Resource::External,
77668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                        mailbox.target(),
777d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        GL_LINEAR,
778d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        0,
779d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        GL_CLAMP_TO_EDGE,
780d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        TextureUsageAny,
781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                        RGBA_8888);
782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  } else {
783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(mailbox.IsSharedMemory());
784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::SharedMemory* shared_memory = mailbox.shared_memory();
785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    DCHECK(shared_memory->memory());
786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(pixels);
7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<SharedBitmap> shared_bitmap;
7891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (shared_bitmap_manager_) {
7901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      shared_bitmap =
7911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory);
7921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
7931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource = Resource(pixels,
7941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        shared_bitmap.release(),
7951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        mailbox.shared_memory_size(),
7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        Resource::External,
7971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        GL_LINEAR,
7981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        GL_CLAMP_TO_EDGE);
799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource.allocated = true;
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource.mailbox = mailbox;
802d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  resource.release_callback =
803d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      base::Bind(&SingleReleaseCallback::Run,
804d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                 base::Owned(release_callback.release()));
80523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  resource.allow_overlay = mailbox.allow_overlay();
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return id;
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::DeleteResource(ResourceId id) {
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceMap::iterator it = resources_.find(id);
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(it != resources_.end());
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Resource* resource = &it->second;
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->marked_for_deletion);
8153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->imported_count, 0);
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->pending_set_pixels || !resource->locked_for_write);
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
818effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (resource->exported_count > 0 || resource->lock_for_read_count > 0) {
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource->marked_for_deletion = true;
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DeleteResourceInternal(it, Normal);
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                              DeleteStyle style) {
8281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal");
8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Resource* resource = &it->second;
8301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool lost_resource = resource->lost;
831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(resource->exported_count == 0 || style != Normal);
8333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (style == ForShutdown && resource->exported_count > 0)
834c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    lost_resource = true;
835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->direct_raster_buffer.reset();
8375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->image_raster_buffer.reset();
8385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->pixel_raster_buffer.reset();
8395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
84090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (resource->image_id) {
8415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin == Resource::Internal);
842a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
843a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id));
84590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource->gl_upload_query_id) {
8475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin == Resource::Internal);
848a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
849a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
850a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
852a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (resource->gl_read_lock_query_id) {
853a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK(resource->origin == Resource::Internal);
854a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    GLES2Interface* gl = ContextGL();
855a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK(gl);
856a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id));
857a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource->gl_pixel_buffer_id) {
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin == Resource::Internal);
860a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
862a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
864010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (resource->origin == Resource::External) {
865010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    DCHECK(resource->mailbox.IsValid());
866a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLuint sync_point = resource->mailbox.sync_point();
8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (resource->type == GLTexture) {
8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(resource->mailbox.IsTexture());
8691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      lost_resource |= lost_output_surface_;
870a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLES2Interface* gl = ContextGL();
871a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      DCHECK(gl);
8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (resource->gl_id) {
873a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        resource->gl_id = 0;
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        if (!lost_resource)
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          sync_point = gl->InsertSyncPointCHROMIUM();
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } else {
879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      DCHECK(resource->mailbox.IsSharedMemory());
880868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::SharedMemory* shared_memory = resource->mailbox.shared_memory();
881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (resource->pixels && shared_memory) {
882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        DCHECK(shared_memory->memory() == resource->pixels);
883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        resource->pixels = NULL;
8841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        delete resource->shared_bitmap;
8851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        resource->shared_bitmap = NULL;
886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      }
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
888d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    resource->release_callback.Run(sync_point, lost_resource);
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
890010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (resource->gl_id) {
8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(gl);
8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->gl_id = 0;
8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
8961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (resource->shared_bitmap) {
8975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin != Resource::External);
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_EQ(Bitmap, resource->type);
8991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    delete resource->shared_bitmap;
9001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource->pixels = NULL;
9011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
9025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->pixels) {
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin == Resource::Internal);
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete[] resource->pixels;
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resources_.erase(it);
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ResourceType ResourceProvider::GetResourceType(
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceId id) {
9113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return GetResource(id)->type;
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::SetPixels(ResourceId id,
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const uint8_t* image,
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 const gfx::Rect& image_rect,
9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 const gfx::Rect& source_rect,
9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 const gfx::Vector2d& dest_offset) {
9193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->locked_for_write);
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->lock_for_read_count);
9225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
9233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(ReadLockFenceHasPassed(resource));
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LazyAllocate(resource);
9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->type == GLTexture) {
9285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->gl_id);
9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!resource->pending_set_pixels);
93068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
931a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
932a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(texture_uploader_.get());
934a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    texture_uploader_->Upload(image,
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              image_rect,
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              source_rect,
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              dest_offset,
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              resource->format,
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              resource->size);
9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK_EQ(Bitmap, resource->type);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(resource->allocated);
944d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    DCHECK_EQ(RGBA_8888, resource->format);
945effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(source_rect.x() >= image_rect.x());
946effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(source_rect.y() >= image_rect.y());
947effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(source_rect.right() <= image_rect.right());
948effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    DCHECK(source_rect.bottom() <= image_rect.bottom());
949effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SkImageInfo source_info =
950effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        SkImageInfo::MakeN32Premul(source_rect.width(), source_rect.height());
951effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    size_t image_row_bytes = image_rect.width() * 4;
952effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    gfx::Vector2d source_offset = source_rect.origin() - image_rect.origin();
953effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    image += source_offset.y() * image_row_bytes + source_offset.x() * 4;
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedWriteLockSoftware lock(this, id);
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkCanvas* dest = lock.sk_canvas();
957effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    dest->writePixels(
958effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        source_info, image, image_row_bytes, dest_offset.x(), dest_offset.y());
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t ResourceProvider::NumBlockingUploads() {
9632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!texture_uploader_)
9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return texture_uploader_->NumBlockingUploads();
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::MarkPendingUploadsAsNonBlocking() {
9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!texture_uploader_)
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_uploader_->MarkPendingUploadsAsNonBlocking();
9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)size_t ResourceProvider::EstimatedUploadsPerTick() {
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!texture_uploader_)
978a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return 1u;
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
980a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  double textures_per_second = texture_uploader_->EstimatedTexturesPerSecond();
981a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t textures_per_tick = floor(
982a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      kTextureUploadTickRate * textures_per_second);
983a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return textures_per_tick ? textures_per_tick : 1u;
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::FlushUploads() {
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!texture_uploader_)
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_uploader_->Flush();
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::ReleaseCachedData() {
9942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!texture_uploader_)
9952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
9962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  texture_uploader_->ReleaseCachedQueries();
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::TimeTicks ResourceProvider::EstimatedUploadCompletionTime(
1001a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    size_t uploads_per_tick) {
1002a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (lost_output_surface_)
1003a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return base::TimeTicks();
1004a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Software resource uploads happen on impl thread, so don't bother batching
10063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // them up and trying to wait for them to complete.
1007a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!texture_uploader_) {
1008a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return gfx::FrameTime::Now() + base::TimeDelta::FromMicroseconds(
1009a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        base::Time::kMicrosecondsPerSecond * kSoftwareUploadTickRate);
1010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
1011a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1012a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeDelta upload_one_texture_time =
1013a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::TimeDelta::FromMicroseconds(
1014a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          base::Time::kMicrosecondsPerSecond * kTextureUploadTickRate) /
1015a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      uploads_per_tick;
1016a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  size_t total_uploads = NumBlockingUploads() + uploads_per_tick;
1018a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return gfx::FrameTime::Now() + upload_one_texture_time * total_uploads;
10193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
10203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::Flush() {
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1023a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
1024a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (gl)
1025a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl->Flush();
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ResourceProvider::Finish() {
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1030a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
1031a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (gl)
1032a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl->Finish();
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceProvider::ShallowFlushIfSupported() {
10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1037a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
1038a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!gl)
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1041a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl->ShallowFlushCHROMIUM();
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ResourceProvider::Resource* ResourceProvider::GetResource(ResourceId id) {
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceMap::iterator it = resources_.find(id);
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(it != resources_.end());
10493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &it->second;
10503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
10513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
10523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
10533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(!resource->locked_for_write ||
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         resource->set_pixels_completion_forced) <<
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      "locked for write: " << resource->locked_for_write <<
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      " pixels completion forced: " << resource->set_pixels_completion_forced;
10583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Uninitialized! Call SetPixels or LockForWrite first.
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->allocated);
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  LazyCreate(resource);
1063a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->type == GLTexture && !resource->gl_id) {
10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin != Resource::Internal);
10665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->mailbox.IsTexture());
10675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
10685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(gl);
10695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (resource->mailbox.sync_point()) {
10705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
10715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource->mailbox.set_sync_point(0);
10725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
10735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->gl_id = texture_id_allocator_->NextId();
10745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
10755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLC(gl,
10765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gl->ConsumeTextureCHROMIUM(resource->mailbox.target(),
10775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   resource->mailbox.name()));
10785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
10795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!resource->pixels && resource->has_shared_bitmap_id &&
10815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shared_bitmap_manager_) {
10825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<SharedBitmap> bitmap =
10835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        shared_bitmap_manager_->GetSharedBitmapFromId(
10845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            resource->size, resource->shared_bitmap_id);
10855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (bitmap) {
10865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource->shared_bitmap = bitmap.release();
10875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource->pixels = resource->shared_bitmap->pixels();
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->lock_for_read_count++;
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource->enable_read_lock_fences)
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource->read_lock_fence = current_read_lock_fence_;
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return resource;
10962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::UnlockForRead(ResourceId id) {
1099effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
1100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  ResourceMap::iterator it = resources_.find(id);
1101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  CHECK(it != resources_.end());
1102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Resource* resource = &it->second;
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_GT(resource->lock_for_read_count, 0);
11053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->lock_for_read_count--;
1107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (resource->marked_for_deletion && !resource->lock_for_read_count) {
1108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (!resource->child_id) {
1109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // The resource belongs to this ResourceProvider, so it can be destroyed.
1110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      DeleteResourceInternal(it, Normal);
1111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    } else {
1112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ChildMap::iterator child_it = children_.find(resource->child_id);
1113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      ResourceIdArray unused;
1114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      unused.push_back(id);
1115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
1116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
1117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ResourceProvider::Resource* ResourceProvider::LockForWrite(
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceId id) {
11223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->locked_for_write);
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->lock_for_read_count);
11253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
11265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
112768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!resource->lost);
11282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(ReadLockFenceHasPassed(resource));
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LazyAllocate(resource);
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->locked_for_write = true;
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return resource;
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceProvider::CanLockForWrite(ResourceId id) {
11363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
113768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return !resource->locked_for_write && !resource->lock_for_read_count &&
11385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         !resource->exported_count && resource->origin == Resource::Internal &&
11395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         !resource->lost && ReadLockFenceHasPassed(resource);
11402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::UnlockForWrite(ResourceId id) {
11433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->locked_for_write);
11453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
11465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->locked_for_write = false;
11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider,
11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id)
11532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : resource_provider_(resource_provider),
11542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id_(resource_id),
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texture_id_(resource_provider->LockForRead(resource_id)->gl_id) {
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture_id_);
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->UnlockForRead(resource_id_);
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider,
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id,
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum filter)
1167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : ScopedReadLockGL(resource_provider, resource_id),
1168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      unit_(GL_TEXTURE0),
1169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
1170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
1173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ResourceProvider* resource_provider,
1174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ResourceProvider::ResourceId resource_id,
1175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    GLenum unit,
1176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    GLenum filter)
1177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : ScopedReadLockGL(resource_provider, resource_id),
1178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      unit_(unit),
1179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
1180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {
11832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
11862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider,
11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id)
11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : resource_provider_(resource_provider),
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id_(resource_id),
11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      texture_id_(resource_provider->LockForWrite(resource_id)->gl_id) {
11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(texture_id_);
11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->UnlockForWrite(resource_id_);
11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::PopulateSkBitmapWithResource(
11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkBitmap* sk_bitmap, const Resource* resource) {
1200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DCHECK_EQ(RGBA_8888, resource->format);
1201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SkImageInfo info = SkImageInfo::MakeN32Premul(resource->size.width(),
1202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                                resource->size.height());
1203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  sk_bitmap->installPixels(info, resource->pixels, info.minRowBytes());
12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider,
12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id)
12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : resource_provider_(resource_provider),
12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id_(resource_id) {
1211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const Resource* resource = resource_provider->LockForRead(resource_id);
1212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  wrap_mode_ = resource->wrap_mode;
1213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource);
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() {
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->UnlockForRead(resource_id_);
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
12212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider* resource_provider,
12222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceProvider::ResourceId resource_id)
12232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : resource_provider_(resource_provider),
12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      resource_id_(resource_id) {
12252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceProvider::PopulateSkBitmapWithResource(
12262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &sk_bitmap_, resource_provider->LockForWrite(resource_id));
12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(valid());
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sk_canvas_.reset(new SkCanvas(sk_bitmap_));
12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
12322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource_provider_->UnlockForWrite(resource_id_);
12332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12357dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochResourceProvider::ResourceProvider(OutputSurface* output_surface,
12361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                   SharedBitmapManager* shared_bitmap_manager,
1237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                   int highp_threshold_min,
12380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                   bool use_rgba_4444_texture_format,
1239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   size_t id_allocation_chunk_size,
1240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   bool use_distance_field_text)
12412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : output_surface_(output_surface),
12421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      shared_bitmap_manager_(shared_bitmap_manager),
1243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      lost_output_surface_(false),
12447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      highp_threshold_min_(highp_threshold_min),
12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      next_id_(1),
12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      next_child_(1),
12477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      default_resource_type_(InvalidType),
12482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      use_texture_storage_ext_(false),
12492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      use_texture_usage_hint_(false),
1250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      use_compressed_texture_etc1_(false),
12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      max_texture_size_(0),
1252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      best_texture_format_(RGBA_8888),
12530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
12540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      id_allocation_chunk_size_(id_allocation_chunk_size),
1255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      use_sync_query_(false),
1256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      use_distance_field_text_(use_distance_field_text) {
12573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(output_surface_->HasClient());
1258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(id_allocation_chunk_size_);
12593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
12607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ResourceProvider::InitializeSoftware() {
12627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(thread_checker_.CalledOnValidThread());
12637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_NE(Bitmap, default_resource_type_);
12647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CleanUpGLIfNeeded();
12667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
12677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  default_resource_type_ = Bitmap;
12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Pick an arbitrary limit here similar to what hardware might.
12695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  max_texture_size_ = 16 * 1024;
1270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  best_texture_format_ = RGBA_8888;
127190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ResourceProvider::InitializeGL() {
12742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
12757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!texture_uploader_);
12767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_NE(GLTexture, default_resource_type_);
1277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!texture_id_allocator_);
1278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!buffer_id_allocator_);
12797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  default_resource_type_ = GLTexture;
1281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const ContextProvider::Capabilities& caps =
1283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      output_surface_->context_provider()->ContextCapabilities();
1284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool use_bgra = caps.gpu.texture_format_bgra8888;
12865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  use_texture_storage_ext_ = caps.gpu.texture_storage;
12875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  use_texture_usage_hint_ = caps.gpu.texture_usage;
12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1;
12890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  use_sync_query_ = caps.gpu.sync_query;
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
1292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl);
1293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  texture_uploader_ = TextureUploader::Create(gl);
1295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  max_texture_size_ = 0;  // Context expects cleared value.
1296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl, gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_));
12977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra);
1298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  texture_id_allocator_.reset(
1300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new TextureIdAllocator(gl, id_allocation_chunk_size_));
1301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  buffer_id_allocator_.reset(
1302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new BufferIdAllocator(gl, id_allocation_chunk_size_));
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ResourceProvider::CleanUpGLIfNeeded() {
1306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
13077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (default_resource_type_ != GLTexture) {
13087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // We are not in GL mode, but double check before returning.
1309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(!gl);
13107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK(!texture_uploader_);
13117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
13127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl);
1315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if DCHECK_IS_ON
1316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Check that all GL resources has been deleted.
1317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (ResourceMap::const_iterator itr = resources_.begin();
1318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       itr != resources_.end();
1319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++itr) {
1320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_NE(GLTexture, itr->second.type);
1321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif  // DCHECK_IS_ON
1323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  texture_uploader_.reset();
1325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  texture_id_allocator_.reset();
1326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  buffer_id_allocator_.reset();
13277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  Finish();
1328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
133068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int ResourceProvider::CreateChild(const ReturnCallback& return_callback) {
13312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
133268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Child child_info;
133468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  child_info.return_callback = return_callback;
133568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int child = next_child_++;
13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  children_[child] = child_info;
13382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return child;
13392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::DestroyChild(int child_id) {
13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChildMap::iterator it = children_.find(child_id);
13432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(it != children_.end());
1344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DestroyChildInternal(it, Normal);
1345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
1348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                            DeleteStyle style) {
1349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Child& child = it->second;
1352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(style == ForShutdown || !child.marked_for_deletion);
135368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
135468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceIdArray resources_for_child;
135568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin();
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       child_it != child.child_to_parent_map.end();
13583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)       ++child_it) {
13593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ResourceId id = child_it->second;
136068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resources_for_child.push_back(id);
13613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
136268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
136368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // If the child is going away, don't consider any resources in use.
136468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  child.in_use_resources.clear();
1365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  child.marked_for_deletion = true;
136668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteAndReturnUnusedResourcesToChild(it, style, resources_for_child);
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap(
13712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int child) const {
13722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ChildMap::const_iterator it = children_.find(child);
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(it != children_.end());
1375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!it->second.marked_for_deletion);
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return it->second.child_to_parent_map;
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
13802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           TransferableResourceArray* list) {
13812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool need_sync_point = false;
13842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ResourceIdArray::const_iterator it = resources.begin();
13852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != resources.end();
13862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
13872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TransferableResource resource;
1388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    TransferResource(gl, *it, &resource);
13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!resource.mailbox_holder.sync_point && !resource.is_software)
13903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      need_sync_point = true;
13913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ++resources_.find(*it)->second.exported_count;
13923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    list->push_back(resource);
13932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
13942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (need_sync_point) {
1395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
13962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (TransferableResourceArray::iterator it = list->begin();
13972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != list->end();
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++it) {
13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (!it->mailbox_holder.sync_point)
14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        it->mailbox_holder.sync_point = sync_point;
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
14022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::ReceiveFromChild(
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int child, const TransferableResourceArray& resources) {
14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Child& child_info = children_.find(child)->second;
1410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!child_info.marked_for_deletion);
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (TransferableResourceArray::const_iterator it = resources.begin();
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != resources.end();
14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
14143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ResourceIdMap::iterator resource_in_map_it =
14153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        child_info.child_to_parent_map.find(it->id);
14163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (resource_in_map_it != child_info.child_to_parent_map.end()) {
1417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Resource& resource = resources_[resource_in_map_it->second];
1418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      resource.marked_for_deletion = false;
1419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      resource.imported_count++;
14203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      continue;
14213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
14221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
14235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if ((!it->is_software && !gl) ||
14245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (it->is_software && !shared_bitmap_manager_)) {
14251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
14261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      ReturnedResourceArray to_return;
14271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      to_return.push_back(it->ToReturnedResource());
14281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      child_info.return_callback.Run(to_return);
14291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      continue;
14301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
14311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
143268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId local_id = next_id_++;
14331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    Resource& resource = resources_[local_id];
14341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (it->is_software) {
14355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource = Resource(it->mailbox_holder.mailbox,
14365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          it->size,
14375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          Resource::Delegated,
14385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          GL_LINEAR,
143946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE);
14401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    } else {
14415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource = Resource(0,
14421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          it->size,
14435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          Resource::Delegated,
14445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          it->mailbox_holder.texture_target,
14451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          it->filter,
14461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          0,
144746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                          it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
14481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          TextureUsageAny,
14491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                          it->format);
14505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
14515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        it->mailbox_holder.texture_target,
14525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                        it->mailbox_holder.sync_point);
14531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
145468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource.child_id = child;
14552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Don't allocate a texture for a child.
14562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource.allocated = true;
14573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    resource.imported_count = 1;
145868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    child_info.parent_to_child_map[local_id] = it->id;
145968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    child_info.child_to_parent_map[it->id] = local_id;
14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
146368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ResourceProvider::DeclareUsedResourcesFromChild(
146468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int child,
146568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ResourceIdArray& resources_from_child) {
146668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
146768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ChildMap::iterator child_it = children_.find(child);
1469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(child_it != children_.end());
1470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Child& child_info = child_it->second;
1471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!child_info.marked_for_deletion);
147268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  child_info.in_use_resources.clear();
147368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
147468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < resources_from_child.size(); ++i) {
147568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceIdMap::iterator it =
147668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        child_info.child_to_parent_map.find(resources_from_child[i]);
147768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(it != child_info.child_to_parent_map.end());
147868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
147968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId local_id = it->second;
1480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK(!resources_[local_id].marked_for_deletion);
148168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    child_info.in_use_resources.insert(local_id);
148268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
148368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
148468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceIdArray unused;
148568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin();
148668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       it != child_info.child_to_parent_map.end();
148768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       ++it) {
148868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId local_id = it->second;
148968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool resource_is_in_use = child_info.in_use_resources.count(local_id) > 0;
149068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!resource_is_in_use)
149168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      unused.push_back(local_id);
149268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
1493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
149468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
149568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
149668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// static
149768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool ResourceProvider::CompareResourceMapIteratorsByChildId(
149868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::pair<ReturnedResource, ResourceMap::iterator>& a,
149968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::pair<ReturnedResource, ResourceMap::iterator>& b) {
150068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const ResourceMap::iterator& a_it = a.second;
150168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const ResourceMap::iterator& b_it = b.second;
150268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const Resource& a_resource = a_it->second;
150368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const Resource& b_resource = b_it->second;
150468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return a_resource.child_id < b_resource.child_id;
150568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
150668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void ResourceProvider::ReceiveReturnsFromParent(
15083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const ReturnedResourceArray& resources) {
15092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
151168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
151268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int child_id = 0;
151368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ResourceIdArray resources_for_child;
151468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
151568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::vector<std::pair<ReturnedResource, ResourceMap::iterator> >
151668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      sorted_resources;
151768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (ReturnedResourceArray::const_iterator it = resources.begin();
15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != resources.end();
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
152168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId local_id = it->id;
152268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceMap::iterator map_iterator = resources_.find(local_id);
152368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
152468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Resource was already lost (e.g. it belonged to a child that was
152568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // destroyed).
152668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (map_iterator == resources_.end())
152768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      continue;
152868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
152968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    sorted_resources.push_back(
153068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        std::pair<ReturnedResource, ResourceMap::iterator>(*it, map_iterator));
153168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
153268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
153368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::sort(sorted_resources.begin(),
153468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            sorted_resources.end(),
153568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            CompareResourceMapIteratorsByChildId);
153668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ChildMap::iterator child_it = children_.end();
153868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < sorted_resources.size(); ++i) {
153968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResource& returned = sorted_resources[i].first;
154068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceMap::iterator& map_iterator = sorted_resources[i].second;
154168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId local_id = map_iterator->first;
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Resource* resource = &map_iterator->second;
154368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
154468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CHECK_GE(resource->exported_count, returned.count);
154568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource->exported_count -= returned.count;
154668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource->lost |= returned.lost;
15473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (resource->exported_count)
15483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      continue;
154968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Need to wait for the current read lock fence to pass before we can
15515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // recycle this resource.
15525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (resource->enable_read_lock_fences)
15535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      resource->read_lock_fence = current_read_lock_fence_;
15545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (returned.sync_point) {
15565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(!resource->has_shared_bitmap_id);
15575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (resource->origin == Resource::Internal) {
15585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        DCHECK(resource->gl_id);
1559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
15605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      } else {
15615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        DCHECK(!resource->gl_id);
15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        resource->mailbox.set_sync_point(returned.sync_point);
15635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      }
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
156568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
156668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!resource->marked_for_deletion)
156768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      continue;
156868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
156968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (!resource->child_id) {
157068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // The resource belongs to this ResourceProvider, so it can be destroyed.
1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DeleteResourceInternal(map_iterator, Normal);
157268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      continue;
157368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
157468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
15755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->origin == Resource::Delegated);
157668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Delete the resource and return it to the child it came from one.
157768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (resource->child_id != child_id) {
157868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (child_id) {
157968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        DCHECK_NE(resources_for_child.size(), 0u);
1580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        DCHECK(child_it != children_.end());
158168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        DeleteAndReturnUnusedResourcesToChild(
1582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            child_it, Normal, resources_for_child);
158368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        resources_for_child.clear();
158468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
158568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      child_it = children_.find(resource->child_id);
1587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      DCHECK(child_it != children_.end());
158868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      child_id = resource->child_id;
158968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
159068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resources_for_child.push_back(local_id);
159168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
159268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
159368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (child_id) {
159468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK_NE(resources_for_child.size(), 0u);
1595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(child_it != children_.end());
159668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DeleteAndReturnUnusedResourcesToChild(
1597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        child_it, Normal, resources_for_child);
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1601a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ResourceProvider::TransferResource(GLES2Interface* gl,
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        ResourceId id,
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        TransferableResource* resource) {
16043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* source = GetResource(id);
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!source->locked_for_write);
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!source->lock_for_read_count);
1607010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK(source->origin != Resource::External || source->mailbox.IsValid());
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(source->allocated);
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->id = id;
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->format = source->format;
16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->mailbox_holder.texture_target = source->target;
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->filter = source->filter;
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->size = source->size;
161446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  resource->is_repeated = (source->wrap_mode == GL_REPEAT);
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (source->type == Bitmap) {
16175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->mailbox_holder.mailbox = source->shared_bitmap_id;
16181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    resource->is_software = true;
16191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  } else if (!source->mailbox.IsValid()) {
16205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LazyCreate(source);
16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(source->gl_id);
16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(source->origin == Resource::Internal);
16235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLC(gl,
16245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gl->BindTexture(resource->mailbox_holder.texture_target,
16255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        source->gl_id));
16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (source->image_id) {
16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(source->dirty_image);
16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BindImageForSampling(source);
16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
16307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This is a resource allocated by the compositor, we need to produce it.
16317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Don't set a sync point, the caller will do it.
16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name));
1633a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl,
16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gl->ProduceTextureCHROMIUM(resource->mailbox_holder.texture_target,
16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   resource->mailbox_holder.mailbox.name));
16365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    source->mailbox = TextureMailbox(resource->mailbox_holder);
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
16381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DCHECK(source->mailbox.IsTexture());
16395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (source->image_id && source->dirty_image) {
16405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(source->gl_id);
16415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DCHECK(source->origin == Resource::Internal);
16425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GLC(gl,
16435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          gl->BindTexture(resource->mailbox_holder.texture_target,
16445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          source->gl_id));
16455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      BindImageForSampling(source);
16465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
16477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This is either an external resource, or a compositor resource that we
16487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // already exported. Make sure to forward the sync point that we were given.
16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->mailbox_holder.mailbox = source->mailbox.mailbox();
16505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->mailbox_holder.texture_target = source->mailbox.target();
16515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->mailbox_holder.sync_point = source->mailbox.sync_point();
16525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    source->mailbox.set_sync_point(0);
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
165668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
1657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ChildMap::iterator child_it,
165868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DeleteStyle style,
165968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ResourceIdArray& unused) {
166068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(child_it != children_.end());
1662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Child* child_info = &child_it->second;
166368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (unused.empty() && !child_info->marked_for_deletion)
166568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
166668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
166768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ReturnedResourceArray to_return;
166868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1669a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
167068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool need_sync_point = false;
167168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < unused.size(); ++i) {
167268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId local_id = unused[i];
167368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
167468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceMap::iterator it = resources_.find(local_id);
167568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CHECK(it != resources_.end());
167668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Resource& resource = it->second;
167768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
167868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(!resource.locked_for_write);
167968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK_EQ(0u, child_info->in_use_resources.count(local_id));
168068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(child_info->parent_to_child_map.count(local_id));
168168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
168268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ResourceId child_id = child_info->parent_to_child_map[local_id];
168368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DCHECK(child_info->child_to_parent_map.count(child_id));
168468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
16851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool is_lost =
16865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        resource.lost || (resource.type == GLTexture && lost_output_surface_);
1687effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (resource.exported_count > 0 || resource.lock_for_read_count > 0) {
168868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (style != ForShutdown) {
1689effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        // Defer this until we receive the resource back from the parent or
1690effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        // the read lock is released.
169168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        resource.marked_for_deletion = true;
169268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        continue;
169368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      }
169468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
169568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      // We still have an exported_count, so we'll have to lose it.
169668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      is_lost = true;
169768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
169868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (gl && resource.filter != resource.original_filter) {
170068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DCHECK(resource.target);
170168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      DCHECK(resource.gl_id);
170268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl, gl->BindTexture(resource.target, resource.gl_id));
1704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl,
1705a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl->TexParameteri(resource.target,
1706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            GL_TEXTURE_MIN_FILTER,
1707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            resource.original_filter));
1708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl,
1709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl->TexParameteri(resource.target,
1710a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            GL_TEXTURE_MAG_FILTER,
1711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            resource.original_filter));
171268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
171368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
171468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ReturnedResource returned;
171568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned.id = child_id;
171668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned.sync_point = resource.mailbox.sync_point();
17175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!returned.sync_point && resource.type == GLTexture)
171868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      need_sync_point = true;
171968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned.count = resource.imported_count;
172068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    returned.lost = is_lost;
172168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    to_return.push_back(returned);
172268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
172368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    child_info->parent_to_child_map.erase(local_id);
172468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    child_info->child_to_parent_map.erase(child_id);
172568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    resource.imported_count = 0;
172668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    DeleteResourceInternal(it, style);
172768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
172868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (need_sync_point) {
1729a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
1730a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
173168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    for (size_t i = 0; i < to_return.size(); ++i) {
173268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      if (!to_return[i].sync_point)
173368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        to_return[i].sync_point = sync_point;
173468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
173568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
173668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
173768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!to_return.empty())
173868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    child_info->return_callback.Run(to_return);
1739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (child_info->marked_for_deletion &&
1741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      child_info->parent_to_child_map.empty()) {
1742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(child_info->child_to_parent_map.empty());
1743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    children_.erase(child_it);
1744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
174568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
174668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* ResourceProvider::MapDirectRasterBuffer(ResourceId id) {
17485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Resource needs to be locked for write since DirectRasterBuffer writes
17495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // directly to it.
17505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LockForWrite(id);
17515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
17525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!resource->direct_raster_buffer.get()) {
17535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->direct_raster_buffer.reset(
1754010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        new DirectRasterBuffer(resource, this, use_distance_field_text_));
17555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
17565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return resource->direct_raster_buffer->LockForWrite();
17575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::UnmapDirectRasterBuffer(ResourceId id) {
17605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
17615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->direct_raster_buffer.get());
17625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->direct_raster_buffer->UnlockForWrite();
17635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UnlockForWrite(id);
17645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* ResourceProvider::MapImageRasterBuffer(ResourceId id) {
17675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
17685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AcquireImage(resource);
17695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!resource->image_raster_buffer.get())
17705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->image_raster_buffer.reset(new ImageRasterBuffer(resource, this));
17715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return resource->image_raster_buffer->LockForWrite();
17725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1774a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool ResourceProvider::UnmapImageRasterBuffer(ResourceId id) {
17753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
17765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->dirty_image = true;
1777a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return resource->image_raster_buffer->UnlockForWrite();
17785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::AcquirePixelRasterBuffer(ResourceId id) {
17815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
17825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AcquirePixelBuffer(resource);
17835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->pixel_raster_buffer.reset(new PixelRasterBuffer(resource, this));
17845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::ReleasePixelRasterBuffer(ResourceId id) {
17875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
17885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->pixel_raster_buffer.reset();
17895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReleasePixelBuffer(resource);
17905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
17925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkCanvas* ResourceProvider::MapPixelRasterBuffer(ResourceId id) {
17935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
17945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->pixel_raster_buffer.get());
17955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return resource->pixel_raster_buffer->LockForWrite();
17965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
17975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ResourceProvider::UnmapPixelRasterBuffer(ResourceId id) {
17995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Resource* resource = GetResource(id);
18005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->pixel_raster_buffer.get());
1801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return resource->pixel_raster_buffer->UnlockForWrite();
18025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::AcquirePixelBuffer(Resource* resource) {
1805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::AcquirePixelBuffer");
1807a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
18093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
181090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!resource->image_id);
18111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DCHECK_NE(ETC1, resource->format);
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1813a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(GLTexture, resource->type);
1814a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GLES2Interface* gl = ContextGL();
1815a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(gl);
1816a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!resource->gl_pixel_buffer_id)
1817a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId();
1818a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1819a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 resource->gl_pixel_buffer_id);
1820a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
1821a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1822a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 resource->size.height() *
1823a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     RoundUp(bytes_per_pixel * resource->size.width(), 4u),
1824a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 NULL,
1825a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 GL_DYNAMIC_DRAW);
1826a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::ReleasePixelBuffer(Resource* resource) {
1830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1831a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::ReleasePixelBuffer");
1832a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
18343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
183590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!resource->image_id);
18362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The pixel buffer can be released while there is a pending "set pixels"
18387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // if completion has been forced. Any shared memory associated with this
18397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // pixel buffer will not be freed until the waitAsyncTexImage2DCHROMIUM
18407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // command has been processed on the service side. It is also safe to
18417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // reuse any query id associated with this resource before they complete
18427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // as each new query has a unique submit count.
18437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (resource->pending_set_pixels) {
18447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    DCHECK(resource->set_pixels_completion_forced);
18457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    resource->pending_set_pixels = false;
18465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->locked_for_write = false;
18477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
18487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1849a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(GLTexture, resource->type);
1850a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!resource->gl_pixel_buffer_id)
1851a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return;
1852a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GLES2Interface* gl = ContextGL();
1853a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(gl);
1854a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1855a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 resource->gl_pixel_buffer_id);
1856a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BufferData(
1857a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW);
1858a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
18592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource,
18625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          int* stride) {
1863a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1864a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::MapPixelBuffer");
1865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
18673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
186890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!resource->image_id);
18692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *stride = 0;
1871a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(GLTexture, resource->type);
1872a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GLES2Interface* gl = ContextGL();
1873a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(gl);
1874a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(resource->gl_pixel_buffer_id);
1875a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1876a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 resource->gl_pixel_buffer_id);
1877a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
1878a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
1879a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
1880a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Buffer is required to be 4-byte aligned.
1881a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  CHECK(!(reinterpret_cast<intptr_t>(image) & 3));
1882a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return image;
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::UnmapPixelBuffer(const Resource* resource) {
1886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::UnmapPixelBuffer");
1888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
18903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
189190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!resource->image_id);
18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1893a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(GLTexture, resource->type);
1894a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GLES2Interface* gl = ContextGL();
1895a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(gl);
1896a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(resource->gl_pixel_buffer_id);
1897a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1898a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 resource->gl_pixel_buffer_id);
1899a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
1900a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GLenum ResourceProvider::BindForSampling(
1904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ResourceProvider::ResourceId resource_id,
1905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GLenum unit,
1906f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GLenum filter) {
19072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
19092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceMap::iterator it = resources_.find(resource_id);
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(it != resources_.end());
19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Resource* resource = &it->second;
19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->lock_for_read_count);
19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->locked_for_write || resource->set_pixels_completion_forced);
19142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1915a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ScopedSetActiveTexture scoped_active_tex(gl, unit);
1916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GLenum target = resource->target;
1917a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl, gl->BindTexture(target, resource->gl_id));
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (filter != resource->filter) {
1919a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter));
1920a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter));
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resource->filter = filter;
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1923a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
19245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->image_id && resource->dirty_image)
19255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    BindImageForSampling(resource);
1926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return target;
19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::BeginSetPixels(ResourceId id) {
1931a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1932a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::BeginSetPixels");
1933a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
19343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
19352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->pending_set_pixels);
1936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LazyCreate(resource);
19385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->gl_id || resource->allocated);
19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(ReadLockFenceHasPassed(resource));
194190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(!resource->image_id);
19422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool allocate = !resource->allocated;
19442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->allocated = true;
19452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LockForWrite(id);
19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1947a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(GLTexture, resource->type);
1948a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(resource->gl_id);
1949a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  GLES2Interface* gl = ContextGL();
1950a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(gl);
1951a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(resource->gl_pixel_buffer_id);
1952a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
1953a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
1954a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1955a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 resource->gl_pixel_buffer_id);
1956a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!resource->gl_upload_query_id)
1957a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gl->GenQueriesEXT(1, &resource->gl_upload_query_id);
1958a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
1959a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                    resource->gl_upload_query_id);
1960a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (allocate) {
1961a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
1962a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                0, /* level */
1963a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                GLInternalFormat(resource->format),
1964a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                resource->size.width(),
1965a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                resource->size.height(),
1966a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                0, /* border */
1967a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                GLDataFormat(resource->format),
1968a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                GLDataType(resource->format),
1969a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                NULL);
19705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1971a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
1972a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   0, /* level */
1973a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   0, /* x */
1974a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   0, /* y */
1975a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   resource->size.width(),
1976a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   resource->size.height(),
1977a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   GLDataFormat(resource->format),
1978a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   GLDataType(resource->format),
1979a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   NULL);
1980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
1981a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
1982a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
19832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->pending_set_pixels = true;
19852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->set_pixels_completion_forced = false;
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
19872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
1989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::ForceSetPixelsToComplete");
1991a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
19923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
19932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->locked_for_write);
19942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->pending_set_pixels);
19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!resource->set_pixels_completion_forced);
19962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource->gl_id) {
1998a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
1999a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
2000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->WaitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D));
2001a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl, gl->BindTexture(GL_TEXTURE_2D, 0));
20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->set_pixels_completion_forced = true;
20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceProvider::DidSetPixelsComplete(ResourceId id) {
2008a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
2009a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "ResourceProvider::DidSetPixelsComplete");
2010a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
20113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
20122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->locked_for_write);
20132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource->pending_set_pixels);
20142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource->gl_id) {
2016a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
2017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
20182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(resource->gl_upload_query_id);
2019a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLuint complete = 1;
2020a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl->GetQueryObjectuivEXT(
2021a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        resource->gl_upload_query_id, GL_QUERY_RESULT_AVAILABLE_EXT, &complete);
20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!complete)
20232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
20242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
20252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->pending_set_pixels = false;
20272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UnlockForWrite(id);
20282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
20302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ResourceProvider::CreateForTesting(ResourceId id) {
20333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  LazyCreate(GetResource(id));
2034868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GLenum ResourceProvider::TargetForTesting(ResourceId id) {
20374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Resource* resource = GetResource(id);
20384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return resource->target;
20394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
20404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void ResourceProvider::LazyCreate(Resource* resource) {
20425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->type != GLTexture || resource->origin != Resource::Internal)
2043868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
2044868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->gl_id)
2046868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return;
2047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->texture_pool);
20495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
20505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!resource->mailbox.IsValid());
2051f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  resource->gl_id = texture_id_allocator_->NextId();
20520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
2053a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
2054a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl);
205558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create and set texture properties. Allocation is delayed until needed.
2057a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
2058a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl,
2059a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl->TexParameteri(resource->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
2060a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl,
2061a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl->TexParameteri(resource->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
2062a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl,
2063a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl->TexParameteri(
206468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          resource->target, GL_TEXTURE_WRAP_S, resource->wrap_mode));
2065a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl,
2066a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl->TexParameteri(
206768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          resource->target, GL_TEXTURE_WRAP_T, resource->wrap_mode));
2068a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl,
2069a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl->TexParameteri(
207068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          resource->target, GL_TEXTURE_POOL_CHROMIUM, resource->texture_pool));
2071868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (use_texture_usage_hint_ && resource->hint == TextureUsageFramebuffer) {
2072a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl,
2073a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl->TexParameteri(resource->target,
2074a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GL_TEXTURE_USAGE_ANGLE,
2075a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
2076868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
2077868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
2078868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
20792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::AllocateForTesting(ResourceId id) {
20803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  LazyAllocate(GetResource(id));
20812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
20822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::LazyAllocate(Resource* resource) {
20842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(resource);
2085868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  LazyCreate(resource);
20862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  DCHECK(resource->gl_id || resource->allocated);
20882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (resource->allocated || !resource->gl_id)
20892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
20902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->allocated = true;
2091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size& size = resource->size;
209368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
2094d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ResourceFormat format = resource->format;
2095a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
2096f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (use_texture_storage_ext_ && IsFormatSupportedForStorage(format) &&
2097f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      resource->hint != TextureUsageFramebuffer) {
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLenum storage_format = TextureToStorageFormat(format);
2099a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLC(gl,
2100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        gl->TexStorage2DEXT(
2101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            GL_TEXTURE_2D, 1, storage_format, size.width(), size.height()));
2102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
21031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    // ETC1 does not support preallocation.
21041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (format != ETC1) {
2105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      GLC(gl,
2106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          gl->TexImage2D(GL_TEXTURE_2D,
2107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         0,
2108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         GLInternalFormat(format),
2109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         size.width(),
2110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         size.height(),
2111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         0,
2112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         GLDataFormat(format),
2113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         GLDataType(format),
2114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         NULL));
21151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
2116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
21172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::BindImageForSampling(Resource* resource) {
21205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
21215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->gl_id);
21225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->image_id);
21235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Release image currently bound to texture.
21255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->bound_image_id)
21265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id);
21275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
21285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->bound_image_id = resource->image_id;
21295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resource->dirty_image = false;
21305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
21315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceProvider::EnableReadLockFences(ResourceProvider::ResourceId id,
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            bool enable) {
21343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Resource* resource = GetResource(id);
21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resource->enable_read_lock_fences = enable;
21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::AcquireImage(Resource* resource) {
21395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
21403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
214190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (resource->type != GLTexture)
2143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
2144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (resource->image_id)
2146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
214790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  resource->allocated = true;
2149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
2150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl);
2151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  resource->image_id =
2152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gl->CreateImageCHROMIUM(resource->size.width(),
2153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                              resource->size.height(),
2154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              TextureToStorageFormat(resource->format),
2155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                              GL_IMAGE_MAP_CHROMIUM);
21567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(resource->image_id);
215790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
215890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::ReleaseImage(Resource* resource) {
21605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
21613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
216290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!resource->image_id)
2164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
2165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GLES2Interface* gl = ContextGL();
2167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(gl);
2168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl->DestroyImageCHROMIUM(resource->image_id);
2169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  resource->image_id = 0;
21708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  resource->bound_image_id = 0;
21718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  resource->dirty_image = false;
2172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  resource->allocated = false;
217390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
217490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint8_t* ResourceProvider::MapImage(const Resource* resource, int* stride) {
217690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DCHECK(ReadLockFenceHasPassed(resource));
21775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
21783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
217990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (resource->type == GLTexture) {
21815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(resource->image_id);
2182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
2183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
2184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // MapImageCHROMIUM should be called prior to GetImageParameterivCHROMIUM.
2185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    uint8_t* pixels =
2186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        static_cast<uint8_t*>(gl->MapImageCHROMIUM(resource->image_id));
21875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gl->GetImageParameterivCHROMIUM(
21885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, stride);
2189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return pixels;
2190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
21915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(Bitmap, resource->type);
21925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *stride = 0;
21935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return resource->pixels;
219490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
219590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
21965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ResourceProvider::UnmapImage(const Resource* resource) {
21975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(resource->origin == Resource::Internal);
21983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_EQ(resource->exported_count, 0);
219990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
2200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (resource->image_id) {
2201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    GLES2Interface* gl = ContextGL();
2202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(gl);
2203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gl->UnmapImageCHROMIUM(resource->image_id);
2204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
22051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
22061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2207a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
2208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TRACE_EVENT0("cc", "ResourceProvider::CopyResource");
2209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
2210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Resource* source_resource = GetResource(source_id);
2211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!source_resource->lock_for_read_count);
2212a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(source_resource->origin == Resource::Internal);
2213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(source_resource->exported_count, 0);
2214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(source_resource->allocated);
2215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  LazyCreate(source_resource);
2216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
2217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  Resource* dest_resource = GetResource(dest_id);
2218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!dest_resource->locked_for_write);
2219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(!dest_resource->lock_for_read_count);
2220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(dest_resource->origin == Resource::Internal);
2221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(dest_resource->exported_count, 0);
2222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  LazyCreate(dest_resource);
2223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
2224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(source_resource->type, dest_resource->type);
2225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK_EQ(source_resource->format, dest_resource->format);
2226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DCHECK(source_resource->size == dest_resource->size);
2227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
2228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (source_resource->type == GLTexture) {
2229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    GLES2Interface* gl = ContextGL();
2230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK(gl);
2231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (source_resource->image_id && source_resource->dirty_image) {
2232a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gl->BindTexture(source_resource->target, source_resource->gl_id);
2233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      BindImageForSampling(source_resource);
2234a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    }
22350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(use_sync_query_) << "CHROMIUM_sync_query extension missing";
2236a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (!source_resource->gl_read_lock_query_id)
2237a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      gl->GenQueriesEXT(1, &source_resource->gl_read_lock_query_id);
22380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM,
2239a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                      source_resource->gl_read_lock_query_id);
2240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK(!dest_resource->image_id);
2241a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    dest_resource->allocated = true;
2242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    gl->CopyTextureCHROMIUM(dest_resource->target,
2243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            source_resource->gl_id,
2244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            dest_resource->gl_id,
2245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            0,
2246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            GLInternalFormat(dest_resource->format),
2247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                            GLDataType(dest_resource->format));
2248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // End query and create a read lock fence that will prevent access to
2249a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    // source resource until CopyTextureCHROMIUM command has completed.
22500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
2251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    source_resource->read_lock_fence = make_scoped_refptr(
2252a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        new QueryFence(gl, source_resource->gl_read_lock_query_id));
2253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else {
2254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK_EQ(Bitmap, source_resource->type);
2255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    DCHECK_EQ(RGBA_8888, source_resource->format);
2256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    LazyAllocate(dest_resource);
2257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
2258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    size_t bytes = SharedBitmap::CheckedSizeInBytes(source_resource->size);
2259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    memcpy(dest_resource->pixels, source_resource->pixels, bytes);
2260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
2261a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
2262a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
2263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
2264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GLint active_unit = 0;
2265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
2266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return active_unit;
2267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
2268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GLES2Interface* ResourceProvider::ContextGL() const {
22703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ContextProvider* context_provider = output_surface_->context_provider();
2271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return context_provider ? context_provider->ContextGL() : NULL;
22723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
22733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
22745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class GrContext* ResourceProvider::GrContext() const {
22755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ContextProvider* context_provider = output_surface_->context_provider();
22765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return context_provider ? context_provider->GrContext() : NULL;
22775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
22785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
22792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
2280