Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / cc / resources / resource_provider.cc
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/resources/resource_provider.h"
6
7 #include <algorithm>
8 #include <limits>
9
10 #include "base/containers/hash_tables.h"
11 #include "base/debug/trace_event.h"
12 #include "base/stl_util.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "cc/base/util.h"
16 #include "cc/output/gl_renderer.h"  // For the GLC() macro.
17 #include "cc/resources/platform_color.h"
18 #include "cc/resources/returned_resource.h"
19 #include "cc/resources/shared_bitmap_manager.h"
20 #include "cc/resources/texture_uploader.h"
21 #include "cc/resources/transferable_resource.h"
22 #include "gpu/GLES2/gl2extchromium.h"
23 #include "gpu/command_buffer/client/gles2_interface.h"
24 #include "third_party/khronos/GLES2/gl2.h"
25 #include "third_party/khronos/GLES2/gl2ext.h"
26 #include "third_party/skia/include/core/SkSurface.h"
27 #include "third_party/skia/include/gpu/GrContext.h"
28 #include "third_party/skia/include/gpu/SkGpuDevice.h"
29 #include "ui/gfx/frame_time.h"
30 #include "ui/gfx/rect.h"
31 #include "ui/gfx/vector2d.h"
32
33 using gpu::gles2::GLES2Interface;
34
35 namespace cc {
36
37 class IdAllocator {
38  public:
39   virtual ~IdAllocator() {}
40
41   virtual GLuint NextId() = 0;
42
43  protected:
44   IdAllocator(GLES2Interface* gl, size_t id_allocation_chunk_size)
45       : gl_(gl),
46         id_allocation_chunk_size_(id_allocation_chunk_size),
47         ids_(new GLuint[id_allocation_chunk_size]),
48         next_id_index_(id_allocation_chunk_size) {
49     DCHECK(id_allocation_chunk_size_);
50   }
51
52   GLES2Interface* gl_;
53   const size_t id_allocation_chunk_size_;
54   scoped_ptr<GLuint[]> ids_;
55   size_t next_id_index_;
56 };
57
58 namespace {
59
60 // Measured in seconds.
61 const double kSoftwareUploadTickRate = 0.000250;
62 const double kTextureUploadTickRate = 0.004;
63
64 GLenum TextureToStorageFormat(ResourceFormat format) {
65   GLenum storage_format = GL_RGBA8_OES;
66   switch (format) {
67     case RGBA_8888:
68       break;
69     case BGRA_8888:
70       storage_format = GL_BGRA8_EXT;
71       break;
72     case RGBA_4444:
73     case LUMINANCE_8:
74     case RGB_565:
75     case ETC1:
76       NOTREACHED();
77       break;
78   }
79
80   return storage_format;
81 }
82
83 bool IsFormatSupportedForStorage(ResourceFormat format) {
84   switch (format) {
85     case RGBA_8888:
86     case BGRA_8888:
87       return true;
88     case RGBA_4444:
89     case LUMINANCE_8:
90     case RGB_565:
91     case ETC1:
92       return false;
93   }
94   return false;
95 }
96
97 GrPixelConfig ToGrPixelConfig(ResourceFormat format) {
98   switch (format) {
99     case RGBA_8888:
100       return kRGBA_8888_GrPixelConfig;
101     case BGRA_8888:
102       return kBGRA_8888_GrPixelConfig;
103     case RGBA_4444:
104       return kRGBA_4444_GrPixelConfig;
105     default:
106       break;
107   }
108   DCHECK(false) << "Unsupported resource format.";
109   return kSkia8888_GrPixelConfig;
110 }
111
112 class IdentityAllocator : public SkBitmap::Allocator {
113  public:
114   explicit IdentityAllocator(void* buffer) : buffer_(buffer) {}
115   virtual bool allocPixelRef(SkBitmap* dst, SkColorTable*) OVERRIDE {
116     dst->setPixels(buffer_);
117     return true;
118   }
119
120  private:
121   void* buffer_;
122 };
123
124 void CopyBitmap(const SkBitmap& src,
125                 uint8_t* dst,
126                 SkBitmap::Config dst_config) {
127   SkBitmap dst_bitmap;
128   IdentityAllocator allocator(dst);
129   src.copyTo(&dst_bitmap, dst_config, &allocator);
130   // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
131   // bitmap data. This check will be removed once crbug.com/293728 is fixed.
132   CHECK_EQ(0u, dst_bitmap.rowBytes() % 4);
133 }
134
135 class ScopedSetActiveTexture {
136  public:
137   ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
138       : gl_(gl), unit_(unit) {
139     DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
140
141     if (unit_ != GL_TEXTURE0)
142       GLC(gl_, gl_->ActiveTexture(unit_));
143   }
144
145   ~ScopedSetActiveTexture() {
146     // Active unit being GL_TEXTURE0 is effectively the ground state.
147     if (unit_ != GL_TEXTURE0)
148       GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
149   }
150
151  private:
152   GLES2Interface* gl_;
153   GLenum unit_;
154 };
155
156 class TextureIdAllocator : public IdAllocator {
157  public:
158   TextureIdAllocator(GLES2Interface* gl,
159                      size_t texture_id_allocation_chunk_size)
160       : IdAllocator(gl, texture_id_allocation_chunk_size) {}
161   virtual ~TextureIdAllocator() {
162     gl_->DeleteTextures(id_allocation_chunk_size_ - next_id_index_,
163                         ids_.get() + next_id_index_);
164   }
165
166   // Overridden from IdAllocator:
167   virtual GLuint NextId() OVERRIDE {
168     if (next_id_index_ == id_allocation_chunk_size_) {
169       gl_->GenTextures(id_allocation_chunk_size_, ids_.get());
170       next_id_index_ = 0;
171     }
172
173     return ids_[next_id_index_++];
174   }
175
176  private:
177   DISALLOW_COPY_AND_ASSIGN(TextureIdAllocator);
178 };
179
180 class BufferIdAllocator : public IdAllocator {
181  public:
182   BufferIdAllocator(GLES2Interface* gl, size_t buffer_id_allocation_chunk_size)
183       : IdAllocator(gl, buffer_id_allocation_chunk_size) {}
184   virtual ~BufferIdAllocator() {
185     gl_->DeleteBuffers(id_allocation_chunk_size_ - next_id_index_,
186                        ids_.get() + next_id_index_);
187   }
188
189   // Overridden from IdAllocator:
190   virtual GLuint NextId() OVERRIDE {
191     if (next_id_index_ == id_allocation_chunk_size_) {
192       gl_->GenBuffers(id_allocation_chunk_size_, ids_.get());
193       next_id_index_ = 0;
194     }
195
196     return ids_[next_id_index_++];
197   }
198
199  private:
200   DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator);
201 };
202
203 }  // namespace
204
205 ResourceProvider::Resource::Resource()
206     : child_id(0),
207       gl_id(0),
208       gl_pixel_buffer_id(0),
209       gl_upload_query_id(0),
210       pixels(NULL),
211       pixel_buffer(NULL),
212       lock_for_read_count(0),
213       imported_count(0),
214       exported_count(0),
215       locked_for_write(false),
216       origin(Internal),
217       marked_for_deletion(false),
218       pending_set_pixels(false),
219       set_pixels_completion_forced(false),
220       allocated(false),
221       enable_read_lock_fences(false),
222       read_lock_fence(NULL),
223       size(),
224       target(0),
225       original_filter(0),
226       filter(0),
227       image_id(0),
228       bound_image_id(0),
229       dirty_image(false),
230       texture_pool(0),
231       wrap_mode(0),
232       lost(false),
233       hint(TextureUsageAny),
234       type(InvalidType),
235       format(RGBA_8888),
236       has_shared_bitmap_id(false),
237       shared_bitmap(NULL) {}
238
239 ResourceProvider::Resource::~Resource() {}
240
241 ResourceProvider::Resource::Resource(GLuint texture_id,
242                                      const gfx::Size& size,
243                                      Origin origin,
244                                      GLenum target,
245                                      GLenum filter,
246                                      GLenum texture_pool,
247                                      GLint wrap_mode,
248                                      TextureUsageHint hint,
249                                      ResourceFormat format)
250     : child_id(0),
251       gl_id(texture_id),
252       gl_pixel_buffer_id(0),
253       gl_upload_query_id(0),
254       pixels(NULL),
255       pixel_buffer(NULL),
256       lock_for_read_count(0),
257       imported_count(0),
258       exported_count(0),
259       locked_for_write(false),
260       origin(origin),
261       marked_for_deletion(false),
262       pending_set_pixels(false),
263       set_pixels_completion_forced(false),
264       allocated(false),
265       enable_read_lock_fences(false),
266       read_lock_fence(NULL),
267       size(size),
268       target(target),
269       original_filter(filter),
270       filter(filter),
271       image_id(0),
272       bound_image_id(0),
273       dirty_image(false),
274       texture_pool(texture_pool),
275       wrap_mode(wrap_mode),
276       lost(false),
277       hint(hint),
278       type(GLTexture),
279       format(format),
280       has_shared_bitmap_id(false),
281       shared_bitmap(NULL) {
282   DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
283   DCHECK_EQ(origin == Internal, !!texture_pool);
284 }
285
286 ResourceProvider::Resource::Resource(uint8_t* pixels,
287                                      SharedBitmap* bitmap,
288                                      const gfx::Size& size,
289                                      Origin origin,
290                                      GLenum filter,
291                                      GLint wrap_mode)
292     : child_id(0),
293       gl_id(0),
294       gl_pixel_buffer_id(0),
295       gl_upload_query_id(0),
296       pixels(pixels),
297       pixel_buffer(NULL),
298       lock_for_read_count(0),
299       imported_count(0),
300       exported_count(0),
301       locked_for_write(false),
302       origin(origin),
303       marked_for_deletion(false),
304       pending_set_pixels(false),
305       set_pixels_completion_forced(false),
306       allocated(false),
307       enable_read_lock_fences(false),
308       read_lock_fence(NULL),
309       size(size),
310       target(0),
311       original_filter(filter),
312       filter(filter),
313       image_id(0),
314       bound_image_id(0),
315       dirty_image(false),
316       texture_pool(0),
317       wrap_mode(wrap_mode),
318       lost(false),
319       hint(TextureUsageAny),
320       type(Bitmap),
321       format(RGBA_8888),
322       has_shared_bitmap_id(!!bitmap),
323       shared_bitmap(bitmap) {
324   DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
325   DCHECK(origin == Delegated || pixels);
326   if (bitmap)
327     shared_bitmap_id = bitmap->id();
328 }
329
330 ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
331                                      const gfx::Size& size,
332                                      Origin origin,
333                                      GLenum filter,
334                                      GLint wrap_mode)
335     : child_id(0),
336       gl_id(0),
337       gl_pixel_buffer_id(0),
338       gl_upload_query_id(0),
339       pixels(NULL),
340       pixel_buffer(NULL),
341       lock_for_read_count(0),
342       imported_count(0),
343       exported_count(0),
344       locked_for_write(false),
345       origin(origin),
346       marked_for_deletion(false),
347       pending_set_pixels(false),
348       set_pixels_completion_forced(false),
349       allocated(false),
350       enable_read_lock_fences(false),
351       read_lock_fence(NULL),
352       size(size),
353       target(0),
354       original_filter(filter),
355       filter(filter),
356       image_id(0),
357       bound_image_id(0),
358       dirty_image(false),
359       texture_pool(0),
360       wrap_mode(wrap_mode),
361       lost(false),
362       hint(TextureUsageAny),
363       type(Bitmap),
364       format(RGBA_8888),
365       has_shared_bitmap_id(true),
366       shared_bitmap_id(bitmap_id),
367       shared_bitmap(NULL) {
368   DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
369 }
370
371 ResourceProvider::RasterBuffer::RasterBuffer(
372     const Resource* resource,
373     ResourceProvider* resource_provider)
374     : resource_(resource),
375       resource_provider_(resource_provider),
376       locked_canvas_(NULL),
377       canvas_save_count_(0) {
378   DCHECK(resource_);
379   DCHECK(resource_provider_);
380 }
381
382 ResourceProvider::RasterBuffer::~RasterBuffer() {}
383
384 SkCanvas* ResourceProvider::RasterBuffer::LockForWrite() {
385   DCHECK(!locked_canvas_);
386
387   locked_canvas_ = DoLockForWrite();
388   canvas_save_count_ = locked_canvas_ ? locked_canvas_->save() : 0;
389   return locked_canvas_;
390 }
391
392 void ResourceProvider::RasterBuffer::UnlockForWrite() {
393   if (locked_canvas_) {
394     locked_canvas_->restoreToCount(canvas_save_count_);
395     locked_canvas_ = NULL;
396   }
397   DoUnlockForWrite();
398 }
399
400 ResourceProvider::DirectRasterBuffer::DirectRasterBuffer(
401     const Resource* resource,
402     ResourceProvider* resource_provider)
403     : RasterBuffer(resource, resource_provider) {}
404
405 ResourceProvider::DirectRasterBuffer::~DirectRasterBuffer() {}
406
407 SkCanvas* ResourceProvider::DirectRasterBuffer::DoLockForWrite() {
408   if (!surface_)
409     surface_ = CreateSurface();
410   return surface_ ? surface_->getCanvas() : NULL;
411 }
412
413 void ResourceProvider::DirectRasterBuffer::DoUnlockForWrite() {}
414
415 skia::RefPtr<SkSurface> ResourceProvider::DirectRasterBuffer::CreateSurface() {
416   skia::RefPtr<SkSurface> surface;
417   switch (resource()->type) {
418     case GLTexture: {
419       DCHECK(resource()->gl_id);
420       class GrContext* gr_context = resource_provider()->GrContext();
421       if (gr_context) {
422         GrBackendTextureDesc desc;
423         desc.fFlags = kRenderTarget_GrBackendTextureFlag;
424         desc.fWidth = resource()->size.width();
425         desc.fHeight = resource()->size.height();
426         desc.fConfig = ToGrPixelConfig(resource()->format);
427         desc.fOrigin = kTopLeft_GrSurfaceOrigin;
428         desc.fTextureHandle = resource()->gl_id;
429         skia::RefPtr<GrTexture> gr_texture =
430             skia::AdoptRef(gr_context->wrapBackendTexture(desc));
431         surface = skia::AdoptRef(
432             SkSurface::NewRenderTargetDirect(gr_texture->asRenderTarget()));
433       }
434       break;
435     }
436     case Bitmap: {
437       DCHECK(resource()->pixels);
438       DCHECK_EQ(RGBA_8888, resource()->format);
439       SkImageInfo image_info = SkImageInfo::MakeN32Premul(
440           resource()->size.width(), resource()->size.height());
441       size_t row_bytes = SkBitmap::ComputeRowBytes(SkBitmap::kARGB_8888_Config,
442                                                    resource()->size.width());
443       surface = skia::AdoptRef(SkSurface::NewRasterDirect(
444           image_info, resource()->pixels, row_bytes));
445       break;
446     }
447     default:
448       NOTREACHED();
449   }
450   return surface;
451 }
452
453 ResourceProvider::BitmapRasterBuffer::BitmapRasterBuffer(
454     const Resource* resource,
455     ResourceProvider* resource_provider)
456     : RasterBuffer(resource, resource_provider), mapped_buffer_(NULL) {}
457
458 ResourceProvider::BitmapRasterBuffer::~BitmapRasterBuffer() {}
459
460 SkCanvas* ResourceProvider::BitmapRasterBuffer::DoLockForWrite() {
461   DCHECK(!mapped_buffer_);
462   DCHECK(!raster_canvas_);
463
464   int stride = 0;
465   mapped_buffer_ = MapBuffer(&stride);
466   if (!mapped_buffer_)
467     return NULL;
468
469   switch (resource()->format) {
470     case RGBA_4444:
471       // Use the default stride if we will eventually convert this
472       // bitmap to 4444.
473       raster_bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
474                                resource()->size.width(),
475                                resource()->size.height());
476       raster_bitmap_.allocPixels();
477       break;
478     case RGBA_8888:
479     case BGRA_8888:
480       raster_bitmap_.setConfig(SkBitmap::kARGB_8888_Config,
481                                resource()->size.width(),
482                                resource()->size.height(),
483                                stride);
484       raster_bitmap_.setPixels(mapped_buffer_);
485       break;
486     case LUMINANCE_8:
487     case RGB_565:
488     case ETC1:
489       NOTREACHED();
490       break;
491   }
492   skia::RefPtr<SkBitmapDevice> device =
493       skia::AdoptRef(new SkBitmapDevice(raster_bitmap_));
494   raster_canvas_ = skia::AdoptRef(new SkCanvas(device.get()));
495   return raster_canvas_.get();
496 }
497
498 void ResourceProvider::BitmapRasterBuffer::DoUnlockForWrite() {
499   raster_canvas_.clear();
500
501   SkBitmap::Config buffer_config = SkBitmapConfig(resource()->format);
502   if (mapped_buffer_ && (buffer_config != raster_bitmap_.config()))
503     CopyBitmap(raster_bitmap_, mapped_buffer_, buffer_config);
504   raster_bitmap_.reset();
505
506   UnmapBuffer();
507   mapped_buffer_ = NULL;
508 }
509
510 ResourceProvider::ImageRasterBuffer::ImageRasterBuffer(
511     const Resource* resource,
512     ResourceProvider* resource_provider)
513     : BitmapRasterBuffer(resource, resource_provider) {}
514
515 ResourceProvider::ImageRasterBuffer::~ImageRasterBuffer() {}
516
517 uint8_t* ResourceProvider::ImageRasterBuffer::MapBuffer(int* stride) {
518   return resource_provider()->MapImage(resource(), stride);
519 }
520
521 void ResourceProvider::ImageRasterBuffer::UnmapBuffer() {
522   resource_provider()->UnmapImage(resource());
523 }
524
525 ResourceProvider::PixelRasterBuffer::PixelRasterBuffer(
526     const Resource* resource,
527     ResourceProvider* resource_provider)
528     : BitmapRasterBuffer(resource, resource_provider) {}
529
530 ResourceProvider::PixelRasterBuffer::~PixelRasterBuffer() {}
531
532 uint8_t* ResourceProvider::PixelRasterBuffer::MapBuffer(int* stride) {
533   return resource_provider()->MapPixelBuffer(resource(), stride);
534 }
535
536 void ResourceProvider::PixelRasterBuffer::UnmapBuffer() {
537   resource_provider()->UnmapPixelBuffer(resource());
538 }
539
540 ResourceProvider::Child::Child() : marked_for_deletion(false) {}
541
542 ResourceProvider::Child::~Child() {}
543
544 scoped_ptr<ResourceProvider> ResourceProvider::Create(
545     OutputSurface* output_surface,
546     SharedBitmapManager* shared_bitmap_manager,
547     int highp_threshold_min,
548     bool use_rgba_4444_texture_format,
549     size_t id_allocation_chunk_size) {
550   scoped_ptr<ResourceProvider> resource_provider(
551       new ResourceProvider(output_surface,
552                            shared_bitmap_manager,
553                            highp_threshold_min,
554                            use_rgba_4444_texture_format,
555                            id_allocation_chunk_size));
556
557   bool success = false;
558   if (resource_provider->ContextGL()) {
559     success = resource_provider->InitializeGL();
560   } else {
561     resource_provider->InitializeSoftware();
562     success = true;
563   }
564
565   if (!success)
566     return scoped_ptr<ResourceProvider>();
567
568   DCHECK_NE(InvalidType, resource_provider->default_resource_type());
569   return resource_provider.Pass();
570 }
571
572 ResourceProvider::~ResourceProvider() {
573   while (!children_.empty())
574     DestroyChildInternal(children_.begin(), ForShutdown);
575   while (!resources_.empty())
576     DeleteResourceInternal(resources_.begin(), ForShutdown);
577
578   CleanUpGLIfNeeded();
579 }
580
581 bool ResourceProvider::InUseByConsumer(ResourceId id) {
582   Resource* resource = GetResource(id);
583   return resource->lock_for_read_count > 0 || resource->exported_count > 0 ||
584          resource->lost;
585 }
586
587 bool ResourceProvider::IsLost(ResourceId id) {
588   Resource* resource = GetResource(id);
589   return resource->lost;
590 }
591
592 ResourceProvider::ResourceId ResourceProvider::CreateResource(
593     const gfx::Size& size,
594     GLint wrap_mode,
595     TextureUsageHint hint,
596     ResourceFormat format) {
597   DCHECK(!size.IsEmpty());
598   switch (default_resource_type_) {
599     case GLTexture:
600       return CreateGLTexture(size,
601                              GL_TEXTURE_2D,
602                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
603                              wrap_mode,
604                              hint,
605                              format);
606     case Bitmap:
607       DCHECK_EQ(RGBA_8888, format);
608       return CreateBitmap(size, wrap_mode);
609     case InvalidType:
610       break;
611   }
612
613   LOG(FATAL) << "Invalid default resource type.";
614   return 0;
615 }
616
617 ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
618     const gfx::Size& size,
619     GLenum target,
620     GLint wrap_mode,
621     TextureUsageHint hint,
622     ResourceFormat format) {
623   DCHECK(!size.IsEmpty());
624   switch (default_resource_type_) {
625     case GLTexture:
626       return CreateGLTexture(size,
627                              target,
628                              GL_TEXTURE_POOL_MANAGED_CHROMIUM,
629                              wrap_mode,
630                              hint,
631                              format);
632     case Bitmap:
633       DCHECK_EQ(RGBA_8888, format);
634       return CreateBitmap(size, wrap_mode);
635     case InvalidType:
636       break;
637   }
638
639   LOG(FATAL) << "Invalid default resource type.";
640   return 0;
641 }
642
643 ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
644     const gfx::Size& size,
645     GLenum target,
646     GLenum texture_pool,
647     GLint wrap_mode,
648     TextureUsageHint hint,
649     ResourceFormat format) {
650   DCHECK_LE(size.width(), max_texture_size_);
651   DCHECK_LE(size.height(), max_texture_size_);
652   DCHECK(thread_checker_.CalledOnValidThread());
653
654   ResourceId id = next_id_++;
655   Resource resource(0,
656                     size,
657                     Resource::Internal,
658                     target,
659                     GL_LINEAR,
660                     texture_pool,
661                     wrap_mode,
662                     hint,
663                     format);
664   resource.allocated = false;
665   resources_[id] = resource;
666   return id;
667 }
668
669 ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
670     const gfx::Size& size, GLint wrap_mode) {
671   DCHECK(thread_checker_.CalledOnValidThread());
672
673   scoped_ptr<SharedBitmap> bitmap;
674   if (shared_bitmap_manager_)
675     bitmap = shared_bitmap_manager_->AllocateSharedBitmap(size);
676
677   uint8_t* pixels;
678   if (bitmap)
679     pixels = bitmap->pixels();
680   else
681     pixels = new uint8_t[4 * size.GetArea()];
682   DCHECK(pixels);
683
684   ResourceId id = next_id_++;
685   Resource resource(
686       pixels, bitmap.release(), size, Resource::Internal, GL_LINEAR, wrap_mode);
687   resource.allocated = true;
688   resources_[id] = resource;
689   return id;
690 }
691
692 ResourceProvider::ResourceId
693 ResourceProvider::CreateResourceFromExternalTexture(
694     GLuint texture_target,
695     GLuint texture_id) {
696   DCHECK(thread_checker_.CalledOnValidThread());
697
698   DCHECK(texture_target);
699   DCHECK(texture_id);
700   GLES2Interface* gl = ContextGL();
701   DCHECK(gl);
702   GLC(gl, gl->BindTexture(texture_target, texture_id));
703   GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
704   GLC(gl, gl->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
705   GLC(gl,
706       gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
707   GLC(gl,
708       gl->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
709
710   ResourceId id = next_id_++;
711   Resource resource(texture_id,
712                     gfx::Size(),
713                     Resource::External,
714                     texture_target,
715                     GL_LINEAR,
716                     0,
717                     GL_CLAMP_TO_EDGE,
718                     TextureUsageAny,
719                     RGBA_8888);
720   resource.allocated = true;
721   resources_[id] = resource;
722   return id;
723 }
724
725 ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
726     const TextureMailbox& mailbox,
727     scoped_ptr<SingleReleaseCallback> release_callback) {
728   DCHECK(thread_checker_.CalledOnValidThread());
729   // Just store the information. Mailbox will be consumed in LockForRead().
730   ResourceId id = next_id_++;
731   DCHECK(mailbox.IsValid());
732   Resource& resource = resources_[id];
733   if (mailbox.IsTexture()) {
734     resource = Resource(0,
735                         gfx::Size(),
736                         Resource::External,
737                         mailbox.target(),
738                         GL_LINEAR,
739                         0,
740                         GL_CLAMP_TO_EDGE,
741                         TextureUsageAny,
742                         RGBA_8888);
743   } else {
744     DCHECK(mailbox.IsSharedMemory());
745     base::SharedMemory* shared_memory = mailbox.shared_memory();
746     DCHECK(shared_memory->memory());
747     uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
748     DCHECK(pixels);
749     scoped_ptr<SharedBitmap> shared_bitmap;
750     if (shared_bitmap_manager_) {
751       shared_bitmap =
752           shared_bitmap_manager_->GetBitmapForSharedMemory(shared_memory);
753     }
754     resource = Resource(pixels,
755                         shared_bitmap.release(),
756                         mailbox.shared_memory_size(),
757                         Resource::External,
758                         GL_LINEAR,
759                         GL_CLAMP_TO_EDGE);
760   }
761   resource.allocated = true;
762   resource.mailbox = mailbox;
763   resource.release_callback =
764       base::Bind(&SingleReleaseCallback::Run,
765                  base::Owned(release_callback.release()));
766   return id;
767 }
768
769 void ResourceProvider::DeleteResource(ResourceId id) {
770   DCHECK(thread_checker_.CalledOnValidThread());
771   ResourceMap::iterator it = resources_.find(id);
772   CHECK(it != resources_.end());
773   Resource* resource = &it->second;
774   DCHECK(!resource->lock_for_read_count);
775   DCHECK(!resource->marked_for_deletion);
776   DCHECK_EQ(resource->imported_count, 0);
777   DCHECK(resource->pending_set_pixels || !resource->locked_for_write);
778
779   if (resource->exported_count > 0) {
780     resource->marked_for_deletion = true;
781     return;
782   } else {
783     DeleteResourceInternal(it, Normal);
784   }
785 }
786
787 void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
788                                               DeleteStyle style) {
789   TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal");
790   Resource* resource = &it->second;
791   bool lost_resource = resource->lost;
792
793   DCHECK(resource->exported_count == 0 || style != Normal);
794   if (style == ForShutdown && resource->exported_count > 0)
795     lost_resource = true;
796
797   resource->direct_raster_buffer.reset();
798   resource->image_raster_buffer.reset();
799   resource->pixel_raster_buffer.reset();
800
801   if (resource->image_id) {
802     DCHECK(resource->origin == Resource::Internal);
803     GLES2Interface* gl = ContextGL();
804     DCHECK(gl);
805     GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id));
806   }
807
808   if (resource->gl_upload_query_id) {
809     DCHECK(resource->origin == Resource::Internal);
810     GLES2Interface* gl = ContextGL();
811     DCHECK(gl);
812     GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
813   }
814   if (resource->gl_pixel_buffer_id) {
815     DCHECK(resource->origin == Resource::Internal);
816     GLES2Interface* gl = ContextGL();
817     DCHECK(gl);
818     GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
819   }
820   if (resource->mailbox.IsValid() && resource->origin == Resource::External) {
821     GLuint sync_point = resource->mailbox.sync_point();
822     if (resource->type == GLTexture) {
823       DCHECK(resource->mailbox.IsTexture());
824       lost_resource |= lost_output_surface_;
825       GLES2Interface* gl = ContextGL();
826       DCHECK(gl);
827       if (resource->gl_id) {
828         GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
829         resource->gl_id = 0;
830         if (!lost_resource)
831           sync_point = gl->InsertSyncPointCHROMIUM();
832       }
833     } else {
834       DCHECK(resource->mailbox.IsSharedMemory());
835       base::SharedMemory* shared_memory = resource->mailbox.shared_memory();
836       if (resource->pixels && shared_memory) {
837         DCHECK(shared_memory->memory() == resource->pixels);
838         resource->pixels = NULL;
839         delete resource->shared_bitmap;
840         resource->shared_bitmap = NULL;
841       }
842     }
843     resource->release_callback.Run(sync_point, lost_resource);
844   }
845   if (resource->gl_id && resource->origin != Resource::External) {
846     GLES2Interface* gl = ContextGL();
847     DCHECK(gl);
848     GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
849     resource->gl_id = 0;
850   }
851   if (resource->shared_bitmap) {
852     DCHECK(resource->origin != Resource::External);
853     DCHECK_EQ(Bitmap, resource->type);
854     delete resource->shared_bitmap;
855     resource->pixels = NULL;
856   }
857   if (resource->pixels) {
858     DCHECK(resource->origin == Resource::Internal);
859     delete[] resource->pixels;
860   }
861   if (resource->pixel_buffer) {
862     DCHECK(resource->origin == Resource::Internal);
863     delete[] resource->pixel_buffer;
864   }
865   // We should never delete the texture for a resource created by
866   // CreateResourceFromExternalTexture().
867   DCHECK(!resource->gl_id || resource->origin == Resource::External);
868
869   resources_.erase(it);
870 }
871
872 ResourceProvider::ResourceType ResourceProvider::GetResourceType(
873     ResourceId id) {
874   return GetResource(id)->type;
875 }
876
877 void ResourceProvider::SetPixels(ResourceId id,
878                                  const uint8_t* image,
879                                  const gfx::Rect& image_rect,
880                                  const gfx::Rect& source_rect,
881                                  const gfx::Vector2d& dest_offset) {
882   Resource* resource = GetResource(id);
883   DCHECK(!resource->locked_for_write);
884   DCHECK(!resource->lock_for_read_count);
885   DCHECK(resource->origin == Resource::Internal);
886   DCHECK_EQ(resource->exported_count, 0);
887   DCHECK(ReadLockFenceHasPassed(resource));
888   LazyAllocate(resource);
889
890   if (resource->type == GLTexture) {
891     DCHECK(resource->gl_id);
892     DCHECK(!resource->pending_set_pixels);
893     DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
894     GLES2Interface* gl = ContextGL();
895     DCHECK(gl);
896     DCHECK(texture_uploader_.get());
897     gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
898     texture_uploader_->Upload(image,
899                               image_rect,
900                               source_rect,
901                               dest_offset,
902                               resource->format,
903                               resource->size);
904   } else {
905     DCHECK_EQ(Bitmap, resource->type);
906     DCHECK(resource->allocated);
907     DCHECK_EQ(RGBA_8888, resource->format);
908     SkBitmap src_full;
909     src_full.setConfig(
910         SkBitmap::kARGB_8888_Config, image_rect.width(), image_rect.height());
911     src_full.setPixels(const_cast<uint8_t*>(image));
912     SkBitmap src_subset;
913     SkIRect sk_source_rect = SkIRect::MakeXYWH(source_rect.x(),
914                                                source_rect.y(),
915                                                source_rect.width(),
916                                                source_rect.height());
917     sk_source_rect.offset(-image_rect.x(), -image_rect.y());
918     src_full.extractSubset(&src_subset, sk_source_rect);
919
920     ScopedWriteLockSoftware lock(this, id);
921     SkCanvas* dest = lock.sk_canvas();
922     dest->writePixels(src_subset, dest_offset.x(), dest_offset.y());
923   }
924 }
925
926 size_t ResourceProvider::NumBlockingUploads() {
927   if (!texture_uploader_)
928     return 0;
929
930   return texture_uploader_->NumBlockingUploads();
931 }
932
933 void ResourceProvider::MarkPendingUploadsAsNonBlocking() {
934   if (!texture_uploader_)
935     return;
936
937   texture_uploader_->MarkPendingUploadsAsNonBlocking();
938 }
939
940 size_t ResourceProvider::EstimatedUploadsPerTick() {
941   if (!texture_uploader_)
942     return 1u;
943
944   double textures_per_second = texture_uploader_->EstimatedTexturesPerSecond();
945   size_t textures_per_tick = floor(
946       kTextureUploadTickRate * textures_per_second);
947   return textures_per_tick ? textures_per_tick : 1u;
948 }
949
950 void ResourceProvider::FlushUploads() {
951   if (!texture_uploader_)
952     return;
953
954   texture_uploader_->Flush();
955 }
956
957 void ResourceProvider::ReleaseCachedData() {
958   if (!texture_uploader_)
959     return;
960
961   texture_uploader_->ReleaseCachedQueries();
962 }
963
964 base::TimeTicks ResourceProvider::EstimatedUploadCompletionTime(
965     size_t uploads_per_tick) {
966   if (lost_output_surface_)
967     return base::TimeTicks();
968
969   // Software resource uploads happen on impl thread, so don't bother batching
970   // them up and trying to wait for them to complete.
971   if (!texture_uploader_) {
972     return gfx::FrameTime::Now() + base::TimeDelta::FromMicroseconds(
973         base::Time::kMicrosecondsPerSecond * kSoftwareUploadTickRate);
974   }
975
976   base::TimeDelta upload_one_texture_time =
977       base::TimeDelta::FromMicroseconds(
978           base::Time::kMicrosecondsPerSecond * kTextureUploadTickRate) /
979       uploads_per_tick;
980
981   size_t total_uploads = NumBlockingUploads() + uploads_per_tick;
982   return gfx::FrameTime::Now() + upload_one_texture_time * total_uploads;
983 }
984
985 void ResourceProvider::Flush() {
986   DCHECK(thread_checker_.CalledOnValidThread());
987   GLES2Interface* gl = ContextGL();
988   if (gl)
989     gl->Flush();
990 }
991
992 void ResourceProvider::Finish() {
993   DCHECK(thread_checker_.CalledOnValidThread());
994   GLES2Interface* gl = ContextGL();
995   if (gl)
996     gl->Finish();
997 }
998
999 bool ResourceProvider::ShallowFlushIfSupported() {
1000   DCHECK(thread_checker_.CalledOnValidThread());
1001   GLES2Interface* gl = ContextGL();
1002   if (!gl)
1003     return false;
1004
1005   gl->ShallowFlushCHROMIUM();
1006   return true;
1007 }
1008
1009 ResourceProvider::Resource* ResourceProvider::GetResource(ResourceId id) {
1010   DCHECK(thread_checker_.CalledOnValidThread());
1011   ResourceMap::iterator it = resources_.find(id);
1012   CHECK(it != resources_.end());
1013   return &it->second;
1014 }
1015
1016 const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
1017   Resource* resource = GetResource(id);
1018   DCHECK(!resource->locked_for_write ||
1019          resource->set_pixels_completion_forced) <<
1020       "locked for write: " << resource->locked_for_write <<
1021       " pixels completion forced: " << resource->set_pixels_completion_forced;
1022   DCHECK_EQ(resource->exported_count, 0);
1023   // Uninitialized! Call SetPixels or LockForWrite first.
1024   DCHECK(resource->allocated);
1025
1026   LazyCreate(resource);
1027
1028   if (resource->type == GLTexture && !resource->gl_id) {
1029     DCHECK(resource->origin != Resource::Internal);
1030     DCHECK(resource->mailbox.IsTexture());
1031     GLES2Interface* gl = ContextGL();
1032     DCHECK(gl);
1033     if (resource->mailbox.sync_point()) {
1034       GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
1035       resource->mailbox.set_sync_point(0);
1036     }
1037     resource->gl_id = texture_id_allocator_->NextId();
1038     GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
1039     GLC(gl,
1040         gl->ConsumeTextureCHROMIUM(resource->mailbox.target(),
1041                                    resource->mailbox.name()));
1042   }
1043
1044   if (!resource->pixels && resource->has_shared_bitmap_id &&
1045       shared_bitmap_manager_) {
1046     scoped_ptr<SharedBitmap> bitmap =
1047         shared_bitmap_manager_->GetSharedBitmapFromId(
1048             resource->size, resource->shared_bitmap_id);
1049     if (bitmap) {
1050       resource->shared_bitmap = bitmap.release();
1051       resource->pixels = resource->shared_bitmap->pixels();
1052     }
1053   }
1054
1055   resource->lock_for_read_count++;
1056   if (resource->enable_read_lock_fences)
1057     resource->read_lock_fence = current_read_lock_fence_;
1058
1059   return resource;
1060 }
1061
1062 void ResourceProvider::UnlockForRead(ResourceId id) {
1063   Resource* resource = GetResource(id);
1064   DCHECK_GT(resource->lock_for_read_count, 0);
1065   DCHECK_EQ(resource->exported_count, 0);
1066   resource->lock_for_read_count--;
1067 }
1068
1069 const ResourceProvider::Resource* ResourceProvider::LockForWrite(
1070     ResourceId id) {
1071   Resource* resource = GetResource(id);
1072   DCHECK(!resource->locked_for_write);
1073   DCHECK(!resource->lock_for_read_count);
1074   DCHECK_EQ(resource->exported_count, 0);
1075   DCHECK(resource->origin == Resource::Internal);
1076   DCHECK(!resource->lost);
1077   DCHECK(ReadLockFenceHasPassed(resource));
1078   LazyAllocate(resource);
1079
1080   resource->locked_for_write = true;
1081   return resource;
1082 }
1083
1084 bool ResourceProvider::CanLockForWrite(ResourceId id) {
1085   Resource* resource = GetResource(id);
1086   return !resource->locked_for_write && !resource->lock_for_read_count &&
1087          !resource->exported_count && resource->origin == Resource::Internal &&
1088          !resource->lost && ReadLockFenceHasPassed(resource);
1089 }
1090
1091 void ResourceProvider::UnlockForWrite(ResourceId id) {
1092   Resource* resource = GetResource(id);
1093   DCHECK(resource->locked_for_write);
1094   DCHECK_EQ(resource->exported_count, 0);
1095   DCHECK(resource->origin == Resource::Internal);
1096   resource->locked_for_write = false;
1097 }
1098
1099 ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
1100     ResourceProvider* resource_provider,
1101     ResourceProvider::ResourceId resource_id)
1102     : resource_provider_(resource_provider),
1103       resource_id_(resource_id),
1104       texture_id_(resource_provider->LockForRead(resource_id)->gl_id) {
1105   DCHECK(texture_id_);
1106 }
1107
1108 ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
1109   resource_provider_->UnlockForRead(resource_id_);
1110 }
1111
1112 ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
1113     ResourceProvider* resource_provider,
1114     ResourceProvider::ResourceId resource_id,
1115     GLenum filter)
1116     : ScopedReadLockGL(resource_provider, resource_id),
1117       unit_(GL_TEXTURE0),
1118       target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
1119 }
1120
1121 ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
1122     ResourceProvider* resource_provider,
1123     ResourceProvider::ResourceId resource_id,
1124     GLenum unit,
1125     GLenum filter)
1126     : ScopedReadLockGL(resource_provider, resource_id),
1127       unit_(unit),
1128       target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
1129 }
1130
1131 ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {
1132 }
1133
1134 ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
1135     ResourceProvider* resource_provider,
1136     ResourceProvider::ResourceId resource_id)
1137     : resource_provider_(resource_provider),
1138       resource_id_(resource_id),
1139       texture_id_(resource_provider->LockForWrite(resource_id)->gl_id) {
1140   DCHECK(texture_id_);
1141 }
1142
1143 ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
1144   resource_provider_->UnlockForWrite(resource_id_);
1145 }
1146
1147 void ResourceProvider::PopulateSkBitmapWithResource(
1148     SkBitmap* sk_bitmap, const Resource* resource) {
1149   DCHECK_EQ(RGBA_8888, resource->format);
1150   sk_bitmap->setConfig(SkBitmap::kARGB_8888_Config,
1151                        resource->size.width(),
1152                        resource->size.height());
1153   sk_bitmap->setPixels(resource->pixels);
1154 }
1155
1156 ResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
1157     ResourceProvider* resource_provider,
1158     ResourceProvider::ResourceId resource_id)
1159     : resource_provider_(resource_provider),
1160       resource_id_(resource_id) {
1161   const Resource* resource = resource_provider->LockForRead(resource_id);
1162   wrap_mode_ = resource->wrap_mode;
1163   ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource);
1164 }
1165
1166 ResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() {
1167   resource_provider_->UnlockForRead(resource_id_);
1168 }
1169
1170 ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
1171     ResourceProvider* resource_provider,
1172     ResourceProvider::ResourceId resource_id)
1173     : resource_provider_(resource_provider),
1174       resource_id_(resource_id) {
1175   ResourceProvider::PopulateSkBitmapWithResource(
1176       &sk_bitmap_, resource_provider->LockForWrite(resource_id));
1177   DCHECK(valid());
1178   sk_canvas_.reset(new SkCanvas(sk_bitmap_));
1179 }
1180
1181 ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
1182   resource_provider_->UnlockForWrite(resource_id_);
1183 }
1184
1185 ResourceProvider::ResourceProvider(OutputSurface* output_surface,
1186                                    SharedBitmapManager* shared_bitmap_manager,
1187                                    int highp_threshold_min,
1188                                    bool use_rgba_4444_texture_format,
1189                                    size_t id_allocation_chunk_size)
1190     : output_surface_(output_surface),
1191       shared_bitmap_manager_(shared_bitmap_manager),
1192       lost_output_surface_(false),
1193       highp_threshold_min_(highp_threshold_min),
1194       next_id_(1),
1195       next_child_(1),
1196       default_resource_type_(InvalidType),
1197       use_texture_storage_ext_(false),
1198       use_texture_usage_hint_(false),
1199       use_compressed_texture_etc1_(false),
1200       max_texture_size_(0),
1201       best_texture_format_(RGBA_8888),
1202       use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
1203       id_allocation_chunk_size_(id_allocation_chunk_size) {
1204   DCHECK(output_surface_->HasClient());
1205   DCHECK(id_allocation_chunk_size_);
1206 }
1207
1208 void ResourceProvider::InitializeSoftware() {
1209   DCHECK(thread_checker_.CalledOnValidThread());
1210   DCHECK_NE(Bitmap, default_resource_type_);
1211
1212   CleanUpGLIfNeeded();
1213
1214   default_resource_type_ = Bitmap;
1215   // Pick an arbitrary limit here similar to what hardware might.
1216   max_texture_size_ = 16 * 1024;
1217   best_texture_format_ = RGBA_8888;
1218 }
1219
1220 bool ResourceProvider::InitializeGL() {
1221   DCHECK(thread_checker_.CalledOnValidThread());
1222   DCHECK(!texture_uploader_);
1223   DCHECK_NE(GLTexture, default_resource_type_);
1224   DCHECK(!texture_id_allocator_);
1225   DCHECK(!buffer_id_allocator_);
1226
1227   default_resource_type_ = GLTexture;
1228
1229   const ContextProvider::Capabilities& caps =
1230       output_surface_->context_provider()->ContextCapabilities();
1231
1232   bool use_bgra = caps.gpu.texture_format_bgra8888;
1233   use_texture_storage_ext_ = caps.gpu.texture_storage;
1234   use_texture_usage_hint_ = caps.gpu.texture_usage;
1235   use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1;
1236
1237   GLES2Interface* gl = ContextGL();
1238   DCHECK(gl);
1239
1240   texture_uploader_ = TextureUploader::Create(gl);
1241   max_texture_size_ = 0;  // Context expects cleared value.
1242   GLC(gl, gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_));
1243   best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra);
1244
1245   texture_id_allocator_.reset(
1246       new TextureIdAllocator(gl, id_allocation_chunk_size_));
1247   buffer_id_allocator_.reset(
1248       new BufferIdAllocator(gl, id_allocation_chunk_size_));
1249
1250   return true;
1251 }
1252
1253 void ResourceProvider::CleanUpGLIfNeeded() {
1254   GLES2Interface* gl = ContextGL();
1255   if (default_resource_type_ != GLTexture) {
1256     // We are not in GL mode, but double check before returning.
1257     DCHECK(!gl);
1258     DCHECK(!texture_uploader_);
1259     return;
1260   }
1261
1262   DCHECK(gl);
1263   texture_uploader_.reset();
1264   texture_id_allocator_.reset();
1265   buffer_id_allocator_.reset();
1266   Finish();
1267 }
1268
1269 int ResourceProvider::CreateChild(const ReturnCallback& return_callback) {
1270   DCHECK(thread_checker_.CalledOnValidThread());
1271
1272   Child child_info;
1273   child_info.return_callback = return_callback;
1274
1275   int child = next_child_++;
1276   children_[child] = child_info;
1277   return child;
1278 }
1279
1280 void ResourceProvider::DestroyChild(int child_id) {
1281   ChildMap::iterator it = children_.find(child_id);
1282   DCHECK(it != children_.end());
1283   DestroyChildInternal(it, Normal);
1284 }
1285
1286 void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
1287                                             DeleteStyle style) {
1288   DCHECK(thread_checker_.CalledOnValidThread());
1289
1290   Child& child = it->second;
1291   DCHECK(style == ForShutdown || !child.marked_for_deletion);
1292
1293   ResourceIdArray resources_for_child;
1294
1295   for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin();
1296        child_it != child.child_to_parent_map.end();
1297        ++child_it) {
1298     ResourceId id = child_it->second;
1299     resources_for_child.push_back(id);
1300   }
1301
1302   // If the child is going away, don't consider any resources in use.
1303   child.in_use_resources.clear();
1304   child.marked_for_deletion = true;
1305
1306   DeleteAndReturnUnusedResourcesToChild(it, style, resources_for_child);
1307 }
1308
1309 const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap(
1310     int child) const {
1311   DCHECK(thread_checker_.CalledOnValidThread());
1312   ChildMap::const_iterator it = children_.find(child);
1313   DCHECK(it != children_.end());
1314   DCHECK(!it->second.marked_for_deletion);
1315   return it->second.child_to_parent_map;
1316 }
1317
1318 void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
1319                                            TransferableResourceArray* list) {
1320   DCHECK(thread_checker_.CalledOnValidThread());
1321   GLES2Interface* gl = ContextGL();
1322   bool need_sync_point = false;
1323   for (ResourceIdArray::const_iterator it = resources.begin();
1324        it != resources.end();
1325        ++it) {
1326     TransferableResource resource;
1327     TransferResource(gl, *it, &resource);
1328     if (!resource.mailbox_holder.sync_point && !resource.is_software)
1329       need_sync_point = true;
1330     ++resources_.find(*it)->second.exported_count;
1331     list->push_back(resource);
1332   }
1333   if (need_sync_point) {
1334     GLuint sync_point = gl->InsertSyncPointCHROMIUM();
1335     for (TransferableResourceArray::iterator it = list->begin();
1336          it != list->end();
1337          ++it) {
1338       if (!it->mailbox_holder.sync_point)
1339         it->mailbox_holder.sync_point = sync_point;
1340     }
1341   }
1342 }
1343
1344 void ResourceProvider::ReceiveFromChild(
1345     int child, const TransferableResourceArray& resources) {
1346   DCHECK(thread_checker_.CalledOnValidThread());
1347   GLES2Interface* gl = ContextGL();
1348   Child& child_info = children_.find(child)->second;
1349   DCHECK(!child_info.marked_for_deletion);
1350   for (TransferableResourceArray::const_iterator it = resources.begin();
1351        it != resources.end();
1352        ++it) {
1353     ResourceIdMap::iterator resource_in_map_it =
1354         child_info.child_to_parent_map.find(it->id);
1355     if (resource_in_map_it != child_info.child_to_parent_map.end()) {
1356       Resource& resource = resources_[resource_in_map_it->second];
1357       resource.marked_for_deletion = false;
1358       resource.imported_count++;
1359       continue;
1360     }
1361
1362     if ((!it->is_software && !gl) ||
1363         (it->is_software && !shared_bitmap_manager_)) {
1364       TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
1365       ReturnedResourceArray to_return;
1366       to_return.push_back(it->ToReturnedResource());
1367       child_info.return_callback.Run(to_return);
1368       continue;
1369     }
1370
1371     ResourceId local_id = next_id_++;
1372     Resource& resource = resources_[local_id];
1373     if (it->is_software) {
1374       resource = Resource(it->mailbox_holder.mailbox,
1375                           it->size,
1376                           Resource::Delegated,
1377                           GL_LINEAR,
1378                           GL_CLAMP_TO_EDGE);
1379     } else {
1380       resource = Resource(0,
1381                           it->size,
1382                           Resource::Delegated,
1383                           it->mailbox_holder.texture_target,
1384                           it->filter,
1385                           0,
1386                           GL_CLAMP_TO_EDGE,
1387                           TextureUsageAny,
1388                           it->format);
1389       resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
1390                                         it->mailbox_holder.texture_target,
1391                                         it->mailbox_holder.sync_point);
1392     }
1393     resource.child_id = child;
1394     // Don't allocate a texture for a child.
1395     resource.allocated = true;
1396     resource.imported_count = 1;
1397     child_info.parent_to_child_map[local_id] = it->id;
1398     child_info.child_to_parent_map[it->id] = local_id;
1399   }
1400 }
1401
1402 void ResourceProvider::DeclareUsedResourcesFromChild(
1403     int child,
1404     const ResourceIdArray& resources_from_child) {
1405   DCHECK(thread_checker_.CalledOnValidThread());
1406
1407   ChildMap::iterator child_it = children_.find(child);
1408   DCHECK(child_it != children_.end());
1409   Child& child_info = child_it->second;
1410   DCHECK(!child_info.marked_for_deletion);
1411   child_info.in_use_resources.clear();
1412
1413   for (size_t i = 0; i < resources_from_child.size(); ++i) {
1414     ResourceIdMap::iterator it =
1415         child_info.child_to_parent_map.find(resources_from_child[i]);
1416     DCHECK(it != child_info.child_to_parent_map.end());
1417
1418     ResourceId local_id = it->second;
1419     DCHECK(!resources_[local_id].marked_for_deletion);
1420     child_info.in_use_resources.insert(local_id);
1421   }
1422
1423   ResourceIdArray unused;
1424   for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin();
1425        it != child_info.child_to_parent_map.end();
1426        ++it) {
1427     ResourceId local_id = it->second;
1428     bool resource_is_in_use = child_info.in_use_resources.count(local_id) > 0;
1429     if (!resource_is_in_use)
1430       unused.push_back(local_id);
1431   }
1432   DeleteAndReturnUnusedResourcesToChild(child_it, Normal, unused);
1433 }
1434
1435 // static
1436 bool ResourceProvider::CompareResourceMapIteratorsByChildId(
1437     const std::pair<ReturnedResource, ResourceMap::iterator>& a,
1438     const std::pair<ReturnedResource, ResourceMap::iterator>& b) {
1439   const ResourceMap::iterator& a_it = a.second;
1440   const ResourceMap::iterator& b_it = b.second;
1441   const Resource& a_resource = a_it->second;
1442   const Resource& b_resource = b_it->second;
1443   return a_resource.child_id < b_resource.child_id;
1444 }
1445
1446 void ResourceProvider::ReceiveReturnsFromParent(
1447     const ReturnedResourceArray& resources) {
1448   DCHECK(thread_checker_.CalledOnValidThread());
1449   GLES2Interface* gl = ContextGL();
1450
1451   int child_id = 0;
1452   ResourceIdArray resources_for_child;
1453
1454   std::vector<std::pair<ReturnedResource, ResourceMap::iterator> >
1455       sorted_resources;
1456
1457   for (ReturnedResourceArray::const_iterator it = resources.begin();
1458        it != resources.end();
1459        ++it) {
1460     ResourceId local_id = it->id;
1461     ResourceMap::iterator map_iterator = resources_.find(local_id);
1462
1463     // Resource was already lost (e.g. it belonged to a child that was
1464     // destroyed).
1465     if (map_iterator == resources_.end())
1466       continue;
1467
1468     sorted_resources.push_back(
1469         std::pair<ReturnedResource, ResourceMap::iterator>(*it, map_iterator));
1470   }
1471
1472   std::sort(sorted_resources.begin(),
1473             sorted_resources.end(),
1474             CompareResourceMapIteratorsByChildId);
1475
1476   ChildMap::iterator child_it = children_.end();
1477   for (size_t i = 0; i < sorted_resources.size(); ++i) {
1478     ReturnedResource& returned = sorted_resources[i].first;
1479     ResourceMap::iterator& map_iterator = sorted_resources[i].second;
1480     ResourceId local_id = map_iterator->first;
1481     Resource* resource = &map_iterator->second;
1482
1483     CHECK_GE(resource->exported_count, returned.count);
1484     resource->exported_count -= returned.count;
1485     resource->lost |= returned.lost;
1486     if (resource->exported_count)
1487       continue;
1488
1489     // Need to wait for the current read lock fence to pass before we can
1490     // recycle this resource.
1491     if (resource->enable_read_lock_fences)
1492       resource->read_lock_fence = current_read_lock_fence_;
1493
1494     if (returned.sync_point) {
1495       DCHECK(!resource->has_shared_bitmap_id);
1496       if (resource->origin == Resource::Internal) {
1497         DCHECK(resource->gl_id);
1498         GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
1499       } else {
1500         // Because CreateResourceFromExternalTexture() never be called,
1501         // when enabling delegated compositor.
1502         DCHECK(!resource->gl_id);
1503         resource->mailbox.set_sync_point(returned.sync_point);
1504       }
1505     }
1506
1507     if (!resource->marked_for_deletion)
1508       continue;
1509
1510     if (!resource->child_id) {
1511       // The resource belongs to this ResourceProvider, so it can be destroyed.
1512       DeleteResourceInternal(map_iterator, Normal);
1513       continue;
1514     }
1515
1516     DCHECK(resource->origin == Resource::Delegated);
1517     // Delete the resource and return it to the child it came from one.
1518     if (resource->child_id != child_id) {
1519       if (child_id) {
1520         DCHECK_NE(resources_for_child.size(), 0u);
1521         DCHECK(child_it != children_.end());
1522         DeleteAndReturnUnusedResourcesToChild(
1523             child_it, Normal, resources_for_child);
1524         resources_for_child.clear();
1525       }
1526
1527       child_it = children_.find(resource->child_id);
1528       DCHECK(child_it != children_.end());
1529       child_id = resource->child_id;
1530     }
1531     resources_for_child.push_back(local_id);
1532   }
1533
1534   if (child_id) {
1535     DCHECK_NE(resources_for_child.size(), 0u);
1536     DCHECK(child_it != children_.end());
1537     DeleteAndReturnUnusedResourcesToChild(
1538         child_it, Normal, resources_for_child);
1539   }
1540 }
1541
1542 void ResourceProvider::TransferResource(GLES2Interface* gl,
1543                                         ResourceId id,
1544                                         TransferableResource* resource) {
1545   Resource* source = GetResource(id);
1546   DCHECK(!source->locked_for_write);
1547   DCHECK(!source->lock_for_read_count);
1548   // Because CreateResourceFromExternalTexture() never be called,
1549   // when enabling delegated compositor.
1550   DCHECK(source->origin == Resource::Internal ||
1551          source->origin == Resource::Delegated ||
1552          (source->origin == Resource::External && source->mailbox.IsValid()));
1553   DCHECK(source->allocated);
1554   DCHECK_EQ(source->wrap_mode, GL_CLAMP_TO_EDGE);
1555   resource->id = id;
1556   resource->format = source->format;
1557   resource->mailbox_holder.texture_target = source->target;
1558   resource->filter = source->filter;
1559   resource->size = source->size;
1560
1561   if (source->type == Bitmap) {
1562     resource->mailbox_holder.mailbox = source->shared_bitmap_id;
1563     resource->is_software = true;
1564   } else if (!source->mailbox.IsValid()) {
1565     LazyCreate(source);
1566     DCHECK(source->gl_id);
1567     DCHECK(source->origin == Resource::Internal);
1568     GLC(gl,
1569         gl->BindTexture(resource->mailbox_holder.texture_target,
1570                         source->gl_id));
1571     if (source->image_id) {
1572       DCHECK(source->dirty_image);
1573       BindImageForSampling(source);
1574     }
1575     // This is a resource allocated by the compositor, we need to produce it.
1576     // Don't set a sync point, the caller will do it.
1577     GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name));
1578     GLC(gl,
1579         gl->ProduceTextureCHROMIUM(resource->mailbox_holder.texture_target,
1580                                    resource->mailbox_holder.mailbox.name));
1581     source->mailbox = TextureMailbox(resource->mailbox_holder);
1582   } else {
1583     DCHECK(source->mailbox.IsTexture());
1584     if (source->image_id && source->dirty_image) {
1585       DCHECK(source->gl_id);
1586       DCHECK(source->origin == Resource::Internal);
1587       GLC(gl,
1588           gl->BindTexture(resource->mailbox_holder.texture_target,
1589                           source->gl_id));
1590       BindImageForSampling(source);
1591     }
1592     // This is either an external resource, or a compositor resource that we
1593     // already exported. Make sure to forward the sync point that we were given.
1594     resource->mailbox_holder.mailbox = source->mailbox.mailbox();
1595     resource->mailbox_holder.texture_target = source->mailbox.target();
1596     resource->mailbox_holder.sync_point = source->mailbox.sync_point();
1597     source->mailbox.set_sync_point(0);
1598   }
1599 }
1600
1601 void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
1602     ChildMap::iterator child_it,
1603     DeleteStyle style,
1604     const ResourceIdArray& unused) {
1605   DCHECK(thread_checker_.CalledOnValidThread());
1606   DCHECK(child_it != children_.end());
1607   Child* child_info = &child_it->second;
1608
1609   if (unused.empty() && !child_info->marked_for_deletion)
1610     return;
1611
1612   ReturnedResourceArray to_return;
1613
1614   GLES2Interface* gl = ContextGL();
1615   bool need_sync_point = false;
1616   for (size_t i = 0; i < unused.size(); ++i) {
1617     ResourceId local_id = unused[i];
1618
1619     ResourceMap::iterator it = resources_.find(local_id);
1620     CHECK(it != resources_.end());
1621     Resource& resource = it->second;
1622
1623     DCHECK(!resource.locked_for_write);
1624     DCHECK(!resource.lock_for_read_count);
1625     DCHECK_EQ(0u, child_info->in_use_resources.count(local_id));
1626     DCHECK(child_info->parent_to_child_map.count(local_id));
1627
1628     ResourceId child_id = child_info->parent_to_child_map[local_id];
1629     DCHECK(child_info->child_to_parent_map.count(child_id));
1630
1631     bool is_lost =
1632         resource.lost || (resource.type == GLTexture && lost_output_surface_);
1633     if (resource.exported_count > 0) {
1634       if (style != ForShutdown) {
1635         // Defer this until we receive the resource back from the parent.
1636         resource.marked_for_deletion = true;
1637         continue;
1638       }
1639
1640       // We still have an exported_count, so we'll have to lose it.
1641       is_lost = true;
1642     }
1643
1644     if (gl && resource.filter != resource.original_filter) {
1645       DCHECK(resource.target);
1646       DCHECK(resource.gl_id);
1647
1648       GLC(gl, gl->BindTexture(resource.target, resource.gl_id));
1649       GLC(gl,
1650           gl->TexParameteri(resource.target,
1651                             GL_TEXTURE_MIN_FILTER,
1652                             resource.original_filter));
1653       GLC(gl,
1654           gl->TexParameteri(resource.target,
1655                             GL_TEXTURE_MAG_FILTER,
1656                             resource.original_filter));
1657     }
1658
1659     ReturnedResource returned;
1660     returned.id = child_id;
1661     returned.sync_point = resource.mailbox.sync_point();
1662     if (!returned.sync_point && resource.type == GLTexture)
1663       need_sync_point = true;
1664     returned.count = resource.imported_count;
1665     returned.lost = is_lost;
1666     to_return.push_back(returned);
1667
1668     child_info->parent_to_child_map.erase(local_id);
1669     child_info->child_to_parent_map.erase(child_id);
1670     resource.imported_count = 0;
1671     DeleteResourceInternal(it, style);
1672   }
1673   if (need_sync_point) {
1674     DCHECK(gl);
1675     GLuint sync_point = gl->InsertSyncPointCHROMIUM();
1676     for (size_t i = 0; i < to_return.size(); ++i) {
1677       if (!to_return[i].sync_point)
1678         to_return[i].sync_point = sync_point;
1679     }
1680   }
1681
1682   if (!to_return.empty())
1683     child_info->return_callback.Run(to_return);
1684
1685   if (child_info->marked_for_deletion &&
1686       child_info->parent_to_child_map.empty()) {
1687     DCHECK(child_info->child_to_parent_map.empty());
1688     children_.erase(child_it);
1689   }
1690 }
1691
1692 SkCanvas* ResourceProvider::MapDirectRasterBuffer(ResourceId id) {
1693   // Resource needs to be locked for write since DirectRasterBuffer writes
1694   // directly to it.
1695   LockForWrite(id);
1696   Resource* resource = GetResource(id);
1697   if (!resource->direct_raster_buffer.get()) {
1698     resource->direct_raster_buffer.reset(
1699         new DirectRasterBuffer(resource, this));
1700   }
1701   return resource->direct_raster_buffer->LockForWrite();
1702 }
1703
1704 void ResourceProvider::UnmapDirectRasterBuffer(ResourceId id) {
1705   Resource* resource = GetResource(id);
1706   DCHECK(resource->direct_raster_buffer.get());
1707   resource->direct_raster_buffer->UnlockForWrite();
1708   UnlockForWrite(id);
1709 }
1710
1711 SkCanvas* ResourceProvider::MapImageRasterBuffer(ResourceId id) {
1712   Resource* resource = GetResource(id);
1713   AcquireImage(resource);
1714   if (!resource->image_raster_buffer.get())
1715     resource->image_raster_buffer.reset(new ImageRasterBuffer(resource, this));
1716   return resource->image_raster_buffer->LockForWrite();
1717 }
1718
1719 void ResourceProvider::UnmapImageRasterBuffer(ResourceId id) {
1720   Resource* resource = GetResource(id);
1721   resource->image_raster_buffer->UnlockForWrite();
1722   resource->dirty_image = true;
1723 }
1724
1725 void ResourceProvider::AcquirePixelRasterBuffer(ResourceId id) {
1726   Resource* resource = GetResource(id);
1727   AcquirePixelBuffer(resource);
1728   resource->pixel_raster_buffer.reset(new PixelRasterBuffer(resource, this));
1729 }
1730
1731 void ResourceProvider::ReleasePixelRasterBuffer(ResourceId id) {
1732   Resource* resource = GetResource(id);
1733   resource->pixel_raster_buffer.reset();
1734   ReleasePixelBuffer(resource);
1735 }
1736
1737 SkCanvas* ResourceProvider::MapPixelRasterBuffer(ResourceId id) {
1738   Resource* resource = GetResource(id);
1739   DCHECK(resource->pixel_raster_buffer.get());
1740   return resource->pixel_raster_buffer->LockForWrite();
1741 }
1742
1743 void ResourceProvider::UnmapPixelRasterBuffer(ResourceId id) {
1744   Resource* resource = GetResource(id);
1745   DCHECK(resource->pixel_raster_buffer.get());
1746   resource->pixel_raster_buffer->UnlockForWrite();
1747 }
1748
1749 void ResourceProvider::AcquirePixelBuffer(Resource* resource) {
1750   DCHECK(resource->origin == Resource::Internal);
1751   DCHECK_EQ(resource->exported_count, 0);
1752   DCHECK(!resource->image_id);
1753   DCHECK_NE(ETC1, resource->format);
1754
1755   if (resource->type == GLTexture) {
1756     GLES2Interface* gl = ContextGL();
1757     DCHECK(gl);
1758     if (!resource->gl_pixel_buffer_id)
1759       resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId();
1760     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1761                    resource->gl_pixel_buffer_id);
1762     unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
1763     gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1764                    resource->size.height() *
1765                        RoundUp(bytes_per_pixel * resource->size.width(), 4u),
1766                    NULL,
1767                    GL_DYNAMIC_DRAW);
1768     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
1769   } else {
1770     DCHECK_EQ(Bitmap, resource->type);
1771     if (resource->pixel_buffer)
1772       return;
1773
1774     resource->pixel_buffer = new uint8_t[4 * resource->size.GetArea()];
1775   }
1776 }
1777
1778 void ResourceProvider::ReleasePixelBuffer(Resource* resource) {
1779   DCHECK(resource->origin == Resource::Internal);
1780   DCHECK_EQ(resource->exported_count, 0);
1781   DCHECK(!resource->image_id);
1782
1783   // The pixel buffer can be released while there is a pending "set pixels"
1784   // if completion has been forced. Any shared memory associated with this
1785   // pixel buffer will not be freed until the waitAsyncTexImage2DCHROMIUM
1786   // command has been processed on the service side. It is also safe to
1787   // reuse any query id associated with this resource before they complete
1788   // as each new query has a unique submit count.
1789   if (resource->pending_set_pixels) {
1790     DCHECK(resource->set_pixels_completion_forced);
1791     resource->pending_set_pixels = false;
1792     resource->locked_for_write = false;
1793   }
1794
1795   if (resource->type == GLTexture) {
1796     if (!resource->gl_pixel_buffer_id)
1797       return;
1798     GLES2Interface* gl = ContextGL();
1799     DCHECK(gl);
1800     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1801                    resource->gl_pixel_buffer_id);
1802     gl->BufferData(
1803         GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW);
1804     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
1805   } else {
1806     DCHECK_EQ(Bitmap, resource->type);
1807     if (!resource->pixel_buffer)
1808       return;
1809     delete[] resource->pixel_buffer;
1810     resource->pixel_buffer = NULL;
1811   }
1812 }
1813
1814 uint8_t* ResourceProvider::MapPixelBuffer(const Resource* resource,
1815                                           int* stride) {
1816   DCHECK(resource->origin == Resource::Internal);
1817   DCHECK_EQ(resource->exported_count, 0);
1818   DCHECK(!resource->image_id);
1819
1820   *stride = 0;
1821   if (resource->type == GLTexture) {
1822     GLES2Interface* gl = ContextGL();
1823     DCHECK(gl);
1824     DCHECK(resource->gl_pixel_buffer_id);
1825     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1826                    resource->gl_pixel_buffer_id);
1827     uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
1828         GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
1829     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
1830     // Buffer is required to be 4-byte aligned.
1831     CHECK(!(reinterpret_cast<intptr_t>(image) & 3));
1832     return image;
1833   }
1834   DCHECK_EQ(Bitmap, resource->type);
1835   return resource->pixel_buffer;
1836 }
1837
1838 void ResourceProvider::UnmapPixelBuffer(const Resource* resource) {
1839   DCHECK(resource->origin == Resource::Internal);
1840   DCHECK_EQ(resource->exported_count, 0);
1841   DCHECK(!resource->image_id);
1842
1843   if (resource->type == GLTexture) {
1844     GLES2Interface* gl = ContextGL();
1845     DCHECK(gl);
1846     DCHECK(resource->gl_pixel_buffer_id);
1847     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1848                    resource->gl_pixel_buffer_id);
1849     gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
1850     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
1851   }
1852 }
1853
1854 GLenum ResourceProvider::BindForSampling(
1855     ResourceProvider::ResourceId resource_id,
1856     GLenum unit,
1857     GLenum filter) {
1858   DCHECK(thread_checker_.CalledOnValidThread());
1859   GLES2Interface* gl = ContextGL();
1860   ResourceMap::iterator it = resources_.find(resource_id);
1861   DCHECK(it != resources_.end());
1862   Resource* resource = &it->second;
1863   DCHECK(resource->lock_for_read_count);
1864   DCHECK(!resource->locked_for_write || resource->set_pixels_completion_forced);
1865
1866   ScopedSetActiveTexture scoped_active_tex(gl, unit);
1867   GLenum target = resource->target;
1868   GLC(gl, gl->BindTexture(target, resource->gl_id));
1869   if (filter != resource->filter) {
1870     GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter));
1871     GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter));
1872     resource->filter = filter;
1873   }
1874
1875   if (resource->image_id && resource->dirty_image)
1876     BindImageForSampling(resource);
1877
1878   return target;
1879 }
1880
1881 void ResourceProvider::BeginSetPixels(ResourceId id) {
1882   Resource* resource = GetResource(id);
1883   DCHECK(!resource->pending_set_pixels);
1884
1885   LazyCreate(resource);
1886   DCHECK(resource->origin == Resource::Internal);
1887   DCHECK(resource->gl_id || resource->allocated);
1888   DCHECK(ReadLockFenceHasPassed(resource));
1889   DCHECK(!resource->image_id);
1890
1891   bool allocate = !resource->allocated;
1892   resource->allocated = true;
1893   LockForWrite(id);
1894
1895   if (resource->type == GLTexture) {
1896     DCHECK(resource->gl_id);
1897     GLES2Interface* gl = ContextGL();
1898     DCHECK(gl);
1899     DCHECK(resource->gl_pixel_buffer_id);
1900     DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
1901     gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
1902     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
1903                    resource->gl_pixel_buffer_id);
1904     if (!resource->gl_upload_query_id)
1905       gl->GenQueriesEXT(1, &resource->gl_upload_query_id);
1906     gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
1907                       resource->gl_upload_query_id);
1908     if (allocate) {
1909       gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
1910                                   0, /* level */
1911                                   GLInternalFormat(resource->format),
1912                                   resource->size.width(),
1913                                   resource->size.height(),
1914                                   0, /* border */
1915                                   GLDataFormat(resource->format),
1916                                   GLDataType(resource->format),
1917                                   NULL);
1918     } else {
1919       gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
1920                                      0, /* level */
1921                                      0, /* x */
1922                                      0, /* y */
1923                                      resource->size.width(),
1924                                      resource->size.height(),
1925                                      GLDataFormat(resource->format),
1926                                      GLDataType(resource->format),
1927                                      NULL);
1928     }
1929     gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
1930     gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
1931   } else {
1932     DCHECK_EQ(Bitmap, resource->type);
1933     DCHECK(!resource->mailbox.IsValid());
1934     DCHECK(resource->pixel_buffer);
1935     DCHECK_EQ(RGBA_8888, resource->format);
1936
1937     std::swap(resource->pixels, resource->pixel_buffer);
1938     delete[] resource->pixel_buffer;
1939     resource->pixel_buffer = NULL;
1940   }
1941
1942   resource->pending_set_pixels = true;
1943   resource->set_pixels_completion_forced = false;
1944 }
1945
1946 void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
1947   Resource* resource = GetResource(id);
1948   DCHECK(resource->locked_for_write);
1949   DCHECK(resource->pending_set_pixels);
1950   DCHECK(!resource->set_pixels_completion_forced);
1951
1952   if (resource->gl_id) {
1953     GLES2Interface* gl = ContextGL();
1954     GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
1955     GLC(gl, gl->WaitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D));
1956     GLC(gl, gl->BindTexture(GL_TEXTURE_2D, 0));
1957   }
1958
1959   resource->set_pixels_completion_forced = true;
1960 }
1961
1962 bool ResourceProvider::DidSetPixelsComplete(ResourceId id) {
1963   Resource* resource = GetResource(id);
1964   DCHECK(resource->locked_for_write);
1965   DCHECK(resource->pending_set_pixels);
1966
1967   if (resource->gl_id) {
1968     GLES2Interface* gl = ContextGL();
1969     DCHECK(gl);
1970     DCHECK(resource->gl_upload_query_id);
1971     GLuint complete = 1;
1972     gl->GetQueryObjectuivEXT(
1973         resource->gl_upload_query_id, GL_QUERY_RESULT_AVAILABLE_EXT, &complete);
1974     if (!complete)
1975       return false;
1976   }
1977
1978   resource->pending_set_pixels = false;
1979   UnlockForWrite(id);
1980
1981   return true;
1982 }
1983
1984 void ResourceProvider::CreateForTesting(ResourceId id) {
1985   LazyCreate(GetResource(id));
1986 }
1987
1988 GLenum ResourceProvider::TargetForTesting(ResourceId id) {
1989   Resource* resource = GetResource(id);
1990   return resource->target;
1991 }
1992
1993 void ResourceProvider::LazyCreate(Resource* resource) {
1994   if (resource->type != GLTexture || resource->origin != Resource::Internal)
1995     return;
1996
1997   if (resource->gl_id)
1998     return;
1999
2000   DCHECK(resource->texture_pool);
2001   DCHECK(resource->origin == Resource::Internal);
2002   DCHECK(!resource->mailbox.IsValid());
2003   resource->gl_id = texture_id_allocator_->NextId();
2004
2005   GLES2Interface* gl = ContextGL();
2006   DCHECK(gl);
2007
2008   // Create and set texture properties. Allocation is delayed until needed.
2009   GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
2010   GLC(gl,
2011       gl->TexParameteri(resource->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
2012   GLC(gl,
2013       gl->TexParameteri(resource->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
2014   GLC(gl,
2015       gl->TexParameteri(
2016           resource->target, GL_TEXTURE_WRAP_S, resource->wrap_mode));
2017   GLC(gl,
2018       gl->TexParameteri(
2019           resource->target, GL_TEXTURE_WRAP_T, resource->wrap_mode));
2020   GLC(gl,
2021       gl->TexParameteri(
2022           resource->target, GL_TEXTURE_POOL_CHROMIUM, resource->texture_pool));
2023   if (use_texture_usage_hint_ && resource->hint == TextureUsageFramebuffer) {
2024     GLC(gl,
2025         gl->TexParameteri(resource->target,
2026                           GL_TEXTURE_USAGE_ANGLE,
2027                           GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
2028   }
2029 }
2030
2031 void ResourceProvider::AllocateForTesting(ResourceId id) {
2032   LazyAllocate(GetResource(id));
2033 }
2034
2035 void ResourceProvider::LazyAllocate(Resource* resource) {
2036   DCHECK(resource);
2037   LazyCreate(resource);
2038
2039   DCHECK(resource->gl_id || resource->allocated);
2040   if (resource->allocated || !resource->gl_id)
2041     return;
2042   resource->allocated = true;
2043   GLES2Interface* gl = ContextGL();
2044   gfx::Size& size = resource->size;
2045   DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
2046   ResourceFormat format = resource->format;
2047   GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
2048   if (use_texture_storage_ext_ && IsFormatSupportedForStorage(format) &&
2049       resource->hint != TextureUsageFramebuffer) {
2050     GLenum storage_format = TextureToStorageFormat(format);
2051     GLC(gl,
2052         gl->TexStorage2DEXT(
2053             GL_TEXTURE_2D, 1, storage_format, size.width(), size.height()));
2054   } else {
2055     // ETC1 does not support preallocation.
2056     if (format != ETC1) {
2057       GLC(gl,
2058           gl->TexImage2D(GL_TEXTURE_2D,
2059                          0,
2060                          GLInternalFormat(format),
2061                          size.width(),
2062                          size.height(),
2063                          0,
2064                          GLDataFormat(format),
2065                          GLDataType(format),
2066                          NULL));
2067     }
2068   }
2069 }
2070
2071 void ResourceProvider::BindImageForSampling(Resource* resource) {
2072   GLES2Interface* gl = ContextGL();
2073   DCHECK(resource->gl_id);
2074   DCHECK(resource->image_id);
2075
2076   // Release image currently bound to texture.
2077   if (resource->bound_image_id)
2078     gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id);
2079   gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
2080   resource->bound_image_id = resource->image_id;
2081   resource->dirty_image = false;
2082 }
2083
2084 void ResourceProvider::EnableReadLockFences(ResourceProvider::ResourceId id,
2085                                             bool enable) {
2086   Resource* resource = GetResource(id);
2087   resource->enable_read_lock_fences = enable;
2088 }
2089
2090 void ResourceProvider::AcquireImage(Resource* resource) {
2091   DCHECK(resource->origin == Resource::Internal);
2092   DCHECK_EQ(resource->exported_count, 0);
2093
2094   if (resource->type != GLTexture)
2095     return;
2096
2097   if (resource->image_id)
2098     return;
2099
2100   resource->allocated = true;
2101   GLES2Interface* gl = ContextGL();
2102   DCHECK(gl);
2103   resource->image_id =
2104       gl->CreateImageCHROMIUM(resource->size.width(),
2105                               resource->size.height(),
2106                               TextureToStorageFormat(resource->format));
2107   DCHECK(resource->image_id);
2108 }
2109
2110 void ResourceProvider::ReleaseImage(Resource* resource) {
2111   DCHECK(resource->origin == Resource::Internal);
2112   DCHECK_EQ(resource->exported_count, 0);
2113
2114   if (!resource->image_id)
2115     return;
2116
2117   GLES2Interface* gl = ContextGL();
2118   DCHECK(gl);
2119   gl->DestroyImageCHROMIUM(resource->image_id);
2120   resource->image_id = 0;
2121   resource->bound_image_id = 0;
2122   resource->dirty_image = false;
2123   resource->allocated = false;
2124 }
2125
2126 uint8_t* ResourceProvider::MapImage(const Resource* resource, int* stride) {
2127   DCHECK(ReadLockFenceHasPassed(resource));
2128   DCHECK(resource->origin == Resource::Internal);
2129   DCHECK_EQ(resource->exported_count, 0);
2130
2131   if (resource->type == GLTexture) {
2132     DCHECK(resource->image_id);
2133     GLES2Interface* gl = ContextGL();
2134     DCHECK(gl);
2135     gl->GetImageParameterivCHROMIUM(
2136         resource->image_id, GL_IMAGE_ROWBYTES_CHROMIUM, stride);
2137     return static_cast<uint8_t*>(
2138         gl->MapImageCHROMIUM(resource->image_id, GL_READ_WRITE));
2139   }
2140   DCHECK_EQ(Bitmap, resource->type);
2141   *stride = 0;
2142   return resource->pixels;
2143 }
2144
2145 void ResourceProvider::UnmapImage(const Resource* resource) {
2146   DCHECK(resource->origin == Resource::Internal);
2147   DCHECK_EQ(resource->exported_count, 0);
2148
2149   if (resource->image_id) {
2150     GLES2Interface* gl = ContextGL();
2151     DCHECK(gl);
2152     gl->UnmapImageCHROMIUM(resource->image_id);
2153   }
2154 }
2155
2156 GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
2157   GLint active_unit = 0;
2158   gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
2159   return active_unit;
2160 }
2161
2162 GLES2Interface* ResourceProvider::ContextGL() const {
2163   ContextProvider* context_provider = output_surface_->context_provider();
2164   return context_provider ? context_provider->ContextGL() : NULL;
2165 }
2166
2167 class GrContext* ResourceProvider::GrContext() const {
2168   ContextProvider* context_provider = output_surface_->context_provider();
2169   return context_provider ? context_provider->GrContext() : NULL;
2170 }
2171
2172 }  // namespace cc