- add sources.
[platform/framework/web/crosswalk.git] / src / cc / resources / resource_provider.h
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 #ifndef CC_RESOURCES_RESOURCE_PROVIDER_H_
6 #define CC_RESOURCES_RESOURCE_PROVIDER_H_
7
8 #include <deque>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
13
14 #include "base/basictypes.h"
15 #include "base/callback.h"
16 #include "base/containers/hash_tables.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/threading/thread_checker.h"
19 #include "cc/base/cc_export.h"
20 #include "cc/output/context_provider.h"
21 #include "cc/output/output_surface.h"
22 #include "cc/resources/release_callback.h"
23 #include "cc/resources/resource_format.h"
24 #include "cc/resources/return_callback.h"
25 #include "cc/resources/single_release_callback.h"
26 #include "cc/resources/texture_mailbox.h"
27 #include "cc/resources/transferable_resource.h"
28 #include "third_party/khronos/GLES2/gl2.h"
29 #include "third_party/khronos/GLES2/gl2ext.h"
30 #include "third_party/skia/include/core/SkBitmap.h"
31 #include "third_party/skia/include/core/SkCanvas.h"
32 #include "ui/gfx/size.h"
33
34 namespace WebKit { class WebGraphicsContext3D; }
35
36 namespace gfx {
37 class Rect;
38 class Vector2d;
39 }
40
41 namespace cc {
42 class SharedBitmap;
43 class SharedBitmapManager;
44 class TextureUploader;
45
46 // This class is not thread-safe and can only be called from the thread it was
47 // created on (in practice, the impl thread).
48 class CC_EXPORT ResourceProvider {
49  public:
50   typedef unsigned ResourceId;
51   typedef std::vector<ResourceId> ResourceIdArray;
52   typedef std::set<ResourceId> ResourceIdSet;
53   typedef base::hash_map<ResourceId, ResourceId> ResourceIdMap;
54   enum TextureUsageHint {
55     TextureUsageAny,
56     TextureUsageFramebuffer,
57   };
58   enum ResourceType {
59     InvalidType = 0,
60     GLTexture = 1,
61     Bitmap,
62   };
63
64   static scoped_ptr<ResourceProvider> Create(
65       OutputSurface* output_surface,
66       SharedBitmapManager* shared_bitmap_manager,
67       int highp_threshold_min,
68       bool use_rgba_4444_texture_format,
69       size_t texture_id_allocation_chunk_size);
70   virtual ~ResourceProvider();
71
72   void InitializeSoftware();
73   bool InitializeGL();
74
75   void DidLoseOutputSurface() { lost_output_surface_ = true; }
76
77   int max_texture_size() const { return max_texture_size_; }
78   ResourceFormat memory_efficient_texture_format() const {
79     return use_rgba_4444_texture_format_ ? RGBA_4444 : best_texture_format_;
80   }
81   ResourceFormat best_texture_format() const { return best_texture_format_; }
82   size_t num_resources() const { return resources_.size(); }
83
84   // Checks whether a resource is in use by a consumer.
85   bool InUseByConsumer(ResourceId id);
86
87   bool IsLost(ResourceId id);
88
89   // Producer interface.
90
91   ResourceType default_resource_type() const { return default_resource_type_; }
92   ResourceType GetResourceType(ResourceId id);
93
94   // Creates a resource of the default resource type.
95   ResourceId CreateResource(gfx::Size size,
96                             GLint wrap_mode,
97                             TextureUsageHint hint,
98                             ResourceFormat format);
99
100   // Creates a resource which is tagged as being managed for GPU memory
101   // accounting purposes.
102   ResourceId CreateManagedResource(gfx::Size size,
103                                    GLint wrap_mode,
104                                    TextureUsageHint hint,
105                                    ResourceFormat format);
106
107   // You can also explicitly create a specific resource type.
108   ResourceId CreateGLTexture(gfx::Size size,
109                              GLenum texture_pool,
110                              GLint wrap_mode,
111                              TextureUsageHint hint,
112                              ResourceFormat format);
113
114   ResourceId CreateBitmap(gfx::Size size);
115   // Wraps an external texture into a GL resource.
116   ResourceId CreateResourceFromExternalTexture(
117       unsigned texture_target,
118       unsigned texture_id);
119
120   // Wraps an external texture mailbox into a GL resource.
121   ResourceId CreateResourceFromTextureMailbox(
122       const TextureMailbox& mailbox,
123       scoped_ptr<SingleReleaseCallback> release_callback);
124
125   void DeleteResource(ResourceId id);
126
127   // Update pixels from image, copying source_rect (in image) to dest_offset (in
128   // the resource).
129   void SetPixels(ResourceId id,
130                  const uint8_t* image,
131                  gfx::Rect image_rect,
132                  gfx::Rect source_rect,
133                  gfx::Vector2d dest_offset);
134
135   // Check upload status.
136   size_t NumBlockingUploads();
137   void MarkPendingUploadsAsNonBlocking();
138   double EstimatedUploadsPerSecond();
139   void FlushUploads();
140   void ReleaseCachedData();
141   base::TimeDelta TextureUpdateTickRate();
142
143   // Flush all context operations, kicking uploads and ensuring ordering with
144   // respect to other contexts.
145   void Flush();
146
147   // Finish all context operations, causing any pending callbacks to be
148   // scheduled.
149   void Finish();
150
151   // Only flush the command buffer if supported.
152   // Returns true if the shallow flush occurred, false otherwise.
153   bool ShallowFlushIfSupported();
154
155   // Creates accounting for a child. Returns a child ID.
156   int CreateChild(const ReturnCallback& return_callback);
157
158   // Destroys accounting for the child, deleting all accounted resources.
159   void DestroyChild(int child);
160
161   // Gets the child->parent resource ID map.
162   const ResourceIdMap& GetChildToParentMap(int child) const;
163
164   // Prepares resources to be transfered to the parent, moving them to
165   // mailboxes and serializing meta-data into TransferableResources.
166   // Resources are not removed from the ResourceProvider, but are marked as
167   // "in use".
168   void PrepareSendToParent(const ResourceIdArray& resources,
169                            TransferableResourceArray* transferable_resources);
170
171   // Receives resources from a child, moving them from mailboxes. Resource IDs
172   // passed are in the child namespace, and will be translated to the parent
173   // namespace, added to the child->parent map.
174   // This adds the resources to the working set in the ResourceProvider without
175   // declaring which resources are in use. Use DeclareUsedResourcesFromChild
176   // after calling this method to do that. All calls to ReceiveFromChild should
177   // be followed by a DeclareUsedResourcesFromChild.
178   // NOTE: if the sync_point is set on any TransferableResource, this will
179   // wait on it.
180   void ReceiveFromChild(
181       int child, const TransferableResourceArray& transferable_resources);
182
183   // Once a set of resources have been received, they may or may not be used.
184   // This declares what set of resources are currently in use from the child,
185   // releasing any other resources back to the child.
186   void DeclareUsedResourcesFromChild(
187       int child,
188       const ResourceIdArray& resources_from_child);
189
190   // Receives resources from the parent, moving them from mailboxes. Resource
191   // IDs passed are in the child namespace.
192   // NOTE: if the sync_point is set on any TransferableResource, this will
193   // wait on it.
194   void ReceiveReturnsFromParent(
195       const ReturnedResourceArray& transferable_resources);
196
197   // The following lock classes are part of the ResourceProvider API and are
198   // needed to read and write the resource contents. The user must ensure
199   // that they only use GL locks on GL resources, etc, and this is enforced
200   // by assertions.
201   class CC_EXPORT ScopedReadLockGL {
202    public:
203     ScopedReadLockGL(ResourceProvider* resource_provider,
204                      ResourceProvider::ResourceId resource_id);
205     virtual ~ScopedReadLockGL();
206
207     unsigned texture_id() const { return texture_id_; }
208
209    protected:
210     ResourceProvider* resource_provider_;
211     ResourceProvider::ResourceId resource_id_;
212
213    private:
214     unsigned texture_id_;
215
216     DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL);
217   };
218
219   class CC_EXPORT ScopedSamplerGL : public ScopedReadLockGL {
220    public:
221     ScopedSamplerGL(ResourceProvider* resource_provider,
222                     ResourceProvider::ResourceId resource_id,
223                     GLenum target,
224                     GLenum filter);
225     ScopedSamplerGL(ResourceProvider* resource_provider,
226                     ResourceProvider::ResourceId resource_id,
227                     GLenum target,
228                     GLenum unit,
229                     GLenum filter);
230     virtual ~ScopedSamplerGL();
231
232    private:
233     GLenum target_;
234     GLenum unit_;
235
236     DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL);
237   };
238
239   class CC_EXPORT ScopedWriteLockGL {
240    public:
241     ScopedWriteLockGL(ResourceProvider* resource_provider,
242                       ResourceProvider::ResourceId resource_id);
243     ~ScopedWriteLockGL();
244
245     unsigned texture_id() const { return texture_id_; }
246
247    private:
248     ResourceProvider* resource_provider_;
249     ResourceProvider::ResourceId resource_id_;
250     unsigned texture_id_;
251
252     DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL);
253   };
254
255   class CC_EXPORT ScopedReadLockSoftware {
256    public:
257     ScopedReadLockSoftware(ResourceProvider* resource_provider,
258                            ResourceProvider::ResourceId resource_id);
259     ~ScopedReadLockSoftware();
260
261     const SkBitmap* sk_bitmap() const { return &sk_bitmap_; }
262
263    private:
264     ResourceProvider* resource_provider_;
265     ResourceProvider::ResourceId resource_id_;
266     SkBitmap sk_bitmap_;
267
268     DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware);
269   };
270
271   class CC_EXPORT ScopedWriteLockSoftware {
272    public:
273     ScopedWriteLockSoftware(ResourceProvider* resource_provider,
274                             ResourceProvider::ResourceId resource_id);
275     ~ScopedWriteLockSoftware();
276
277     SkCanvas* sk_canvas() { return sk_canvas_.get(); }
278
279    private:
280     ResourceProvider* resource_provider_;
281     ResourceProvider::ResourceId resource_id_;
282     SkBitmap sk_bitmap_;
283     scoped_ptr<SkCanvas> sk_canvas_;
284
285     DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware);
286   };
287
288   class Fence : public base::RefCounted<Fence> {
289    public:
290     Fence() {}
291     virtual bool HasPassed() = 0;
292
293    protected:
294     friend class base::RefCounted<Fence>;
295     virtual ~Fence() {}
296
297    private:
298     DISALLOW_COPY_AND_ASSIGN(Fence);
299   };
300
301   // Acquire pixel buffer for resource. The pixel buffer can be used to
302   // set resource pixels without performing unnecessary copying.
303   void AcquirePixelBuffer(ResourceId id);
304   void ReleasePixelBuffer(ResourceId id);
305
306   // Map/unmap the acquired pixel buffer.
307   uint8_t* MapPixelBuffer(ResourceId id);
308   void UnmapPixelBuffer(ResourceId id);
309
310   // Asynchronously update pixels from acquired pixel buffer.
311   void BeginSetPixels(ResourceId id);
312   void ForceSetPixelsToComplete(ResourceId id);
313   bool DidSetPixelsComplete(ResourceId id);
314
315   // Acquire and release an image. The image allows direct
316   // manipulation of texture memory.
317   void AcquireImage(ResourceId id);
318   void ReleaseImage(ResourceId id);
319
320   // Maps the acquired image so that its pixels could be modified.
321   // Unmap is called when all pixels are set.
322   uint8_t* MapImage(ResourceId id);
323   void UnmapImage(ResourceId id);
324
325   // Returns the stride for the image.
326   int GetImageStride(ResourceId id);
327
328   base::SharedMemory* GetSharedMemory(ResourceId id);
329
330   // For tests only! This prevents detecting uninitialized reads.
331   // Use SetPixels or LockForWrite to allocate implicitly.
332   void AllocateForTesting(ResourceId id);
333
334   // For tests only!
335   void CreateForTesting(ResourceId id);
336
337   GLint WrapModeForTesting(ResourceId id);
338   GLenum TargetForTesting(ResourceId id);
339
340   // Sets the current read fence. If a resource is locked for read
341   // and has read fences enabled, the resource will not allow writes
342   // until this fence has passed.
343   void SetReadLockFence(scoped_refptr<Fence> fence) {
344     current_read_lock_fence_ = fence;
345   }
346   Fence* GetReadLockFence() { return current_read_lock_fence_.get(); }
347
348   // Enable read lock fences for a specific resource.
349   void EnableReadLockFences(ResourceProvider::ResourceId id, bool enable);
350
351   // Indicates if we can currently lock this resource for write.
352   bool CanLockForWrite(ResourceId id);
353
354   static GLint GetActiveTextureUnit(WebKit::WebGraphicsContext3D* context);
355
356  private:
357   struct Resource {
358     Resource();
359     ~Resource();
360     Resource(unsigned texture_id,
361              gfx::Size size,
362              GLenum target,
363              GLenum filter,
364              GLenum texture_pool,
365              GLint wrap_mode,
366              TextureUsageHint hint,
367              ResourceFormat format);
368     Resource(uint8_t* pixels,
369              SharedBitmap* bitmap,
370              gfx::Size size,
371              GLenum filter,
372              GLint wrap_mode);
373
374     int child_id;
375     unsigned gl_id;
376     // Pixel buffer used for set pixels without unnecessary copying.
377     unsigned gl_pixel_buffer_id;
378     // Query used to determine when asynchronous set pixels complete.
379     unsigned gl_upload_query_id;
380     TextureMailbox mailbox;
381     ReleaseCallback release_callback;
382     uint8_t* pixels;
383     uint8_t* pixel_buffer;
384     int lock_for_read_count;
385     int imported_count;
386     int exported_count;
387     bool locked_for_write;
388     bool external;
389     bool marked_for_deletion;
390     bool pending_set_pixels;
391     bool set_pixels_completion_forced;
392     bool allocated;
393     bool enable_read_lock_fences;
394     scoped_refptr<Fence> read_lock_fence;
395     gfx::Size size;
396     GLenum target;
397     // TODO(skyostil): Use a separate sampler object for filter state.
398     GLenum original_filter;
399     GLenum filter;
400     unsigned image_id;
401     unsigned bound_image_id;
402     bool dirty_image;
403     GLenum texture_pool;
404     GLint wrap_mode;
405     bool lost;
406     TextureUsageHint hint;
407     ResourceType type;
408     ResourceFormat format;
409     SharedBitmap* shared_bitmap;
410   };
411   typedef base::hash_map<ResourceId, Resource> ResourceMap;
412
413   static bool CompareResourceMapIteratorsByChildId(
414       const std::pair<ReturnedResource, ResourceMap::iterator>& a,
415       const std::pair<ReturnedResource, ResourceMap::iterator>& b);
416
417   struct Child {
418     Child();
419     ~Child();
420
421     ResourceIdMap child_to_parent_map;
422     ResourceIdMap parent_to_child_map;
423     ReturnCallback return_callback;
424     ResourceIdSet in_use_resources;
425   };
426   typedef base::hash_map<int, Child> ChildMap;
427
428   bool ReadLockFenceHasPassed(Resource* resource) {
429     return !resource->read_lock_fence.get() ||
430            resource->read_lock_fence->HasPassed();
431   }
432
433   ResourceProvider(OutputSurface* output_surface,
434                    SharedBitmapManager* shared_bitmap_manager,
435                    int highp_threshold_min,
436                    bool use_rgba_4444_texture_format,
437                    size_t texture_id_allocation_chunk_size);
438
439   void CleanUpGLIfNeeded();
440
441   Resource* GetResource(ResourceId id);
442   const Resource* LockForRead(ResourceId id);
443   void UnlockForRead(ResourceId id);
444   const Resource* LockForWrite(ResourceId id);
445   void UnlockForWrite(ResourceId id);
446   static void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap,
447                                            const Resource* resource);
448
449   void TransferResource(WebKit::WebGraphicsContext3D* context,
450                         ResourceId id,
451                         TransferableResource* resource);
452   enum DeleteStyle {
453     Normal,
454     ForShutdown,
455   };
456   void DeleteResourceInternal(ResourceMap::iterator it, DeleteStyle style);
457   void DeleteAndReturnUnusedResourcesToChild(Child* child_info,
458                                              DeleteStyle style,
459                                              const ResourceIdArray& unused);
460   void LazyCreate(Resource* resource);
461   void LazyAllocate(Resource* resource);
462
463   // Binds the given GL resource to a texture target for sampling using the
464   // specified filter for both minification and magnification. The resource
465   // must be locked for reading.
466   void BindForSampling(ResourceProvider::ResourceId resource_id,
467                        GLenum target,
468                        GLenum unit,
469                        GLenum filter);
470
471   // Returns NULL if the output_surface_ does not have a ContextProvider.
472   WebKit::WebGraphicsContext3D* Context3d() const;
473
474   unsigned NextTextureId();
475
476   OutputSurface* output_surface_;
477   SharedBitmapManager* shared_bitmap_manager_;
478   bool lost_output_surface_;
479   int highp_threshold_min_;
480   ResourceId next_id_;
481   ResourceMap resources_;
482   int next_child_;
483   ChildMap children_;
484
485   ResourceType default_resource_type_;
486   bool use_texture_storage_ext_;
487   bool use_texture_usage_hint_;
488   bool use_shallow_flush_;
489   bool use_compressed_texture_etc1_;
490   scoped_ptr<TextureUploader> texture_uploader_;
491   int max_texture_size_;
492   ResourceFormat best_texture_format_;
493
494   base::ThreadChecker thread_checker_;
495
496   scoped_refptr<Fence> current_read_lock_fence_;
497   bool use_rgba_4444_texture_format_;
498
499   size_t texture_id_allocation_chunk_size_;
500   std::deque<unsigned> unused_texture_ids_;
501
502   DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
503 };
504
505
506 // TODO(epenner): Move these format conversions to resource_format.h
507 // once that builds on mac (npapi.h currently #includes OpenGL.h).
508 inline unsigned BitsPerPixel(ResourceFormat format) {
509   DCHECK_LE(format, RESOURCE_FORMAT_MAX);
510   static const unsigned format_bits_per_pixel[RESOURCE_FORMAT_MAX + 1] = {
511     32,  // RGBA_8888
512     16,  // RGBA_4444
513     32,  // BGRA_8888
514     8,   // LUMINANCE_8
515     16,  // RGB_565,
516     4    // ETC1
517   };
518   return format_bits_per_pixel[format];
519 }
520
521 inline GLenum GLDataType(ResourceFormat format) {
522   DCHECK_LE(format, RESOURCE_FORMAT_MAX);
523   static const unsigned format_gl_data_type[RESOURCE_FORMAT_MAX + 1] = {
524     GL_UNSIGNED_BYTE,           // RGBA_8888
525     GL_UNSIGNED_SHORT_4_4_4_4,  // RGBA_4444
526     GL_UNSIGNED_BYTE,           // BGRA_8888
527     GL_UNSIGNED_BYTE,           // LUMINANCE_8
528     GL_UNSIGNED_SHORT_5_6_5,    // RGB_565,
529     GL_UNSIGNED_BYTE            // ETC1
530   };
531   return format_gl_data_type[format];
532 }
533
534 inline GLenum GLDataFormat(ResourceFormat format) {
535   DCHECK_LE(format, RESOURCE_FORMAT_MAX);
536   static const unsigned format_gl_data_format[RESOURCE_FORMAT_MAX + 1] = {
537     GL_RGBA,           // RGBA_8888
538     GL_RGBA,           // RGBA_4444
539     GL_BGRA_EXT,       // BGRA_8888
540     GL_LUMINANCE,      // LUMINANCE_8
541     GL_RGB,            // RGB_565
542     GL_ETC1_RGB8_OES   // ETC1
543   };
544   return format_gl_data_format[format];
545 }
546
547 inline GLenum GLInternalFormat(ResourceFormat format) {
548   return GLDataFormat(format);
549 }
550
551 }  // namespace cc
552
553 #endif  // CC_RESOURCES_RESOURCE_PROVIDER_H_