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