resource_provider.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 <vector>
12
13#include "base/basictypes.h"
14#include "base/callback.h"
15#include "base/hash_tables.h"
16#include "base/memory/scoped_ptr.h"
17#include "base/threading/thread_checker.h"
18#include "cc/base/cc_export.h"
19#include "cc/output/context_provider.h"
20#include "cc/output/output_surface.h"
21#include "cc/output/texture_copier.h"
22#include "cc/resources/texture_mailbox.h"
23#include "cc/resources/transferable_resource.h"
24#include "third_party/khronos/GLES2/gl2.h"
25#include "third_party/skia/include/core/SkBitmap.h"
26#include "third_party/skia/include/core/SkCanvas.h"
27#include "ui/gfx/size.h"
28
29namespace WebKit {
30class WebGraphicsContext3D;
31}
32
33namespace gfx {
34class Rect;
35class Vector2d;
36}
37
38namespace cc {
39class TextureUploader;
40
41// This class is not thread-safe and can only be called from the thread it was
42// created on (in practice, the impl thread).
43class CC_EXPORT ResourceProvider {
44 public:
45  typedef unsigned ResourceId;
46  typedef std::vector<ResourceId> ResourceIdArray;
47  typedef std::set<ResourceId> ResourceIdSet;
48  typedef base::hash_map<ResourceId, ResourceId> ResourceIdMap;
49  enum TextureUsageHint {
50    TextureUsageAny,
51    TextureUsageFramebuffer,
52  };
53  enum ResourceType {
54    GLTexture = 1,
55    Bitmap,
56  };
57
58  static scoped_ptr<ResourceProvider> Create(OutputSurface* output_surface);
59
60  virtual ~ResourceProvider();
61
62  WebKit::WebGraphicsContext3D* GraphicsContext3D();
63  TextureCopier* texture_copier() const { return texture_copier_.get(); }
64  int max_texture_size() const { return max_texture_size_; }
65  GLenum best_texture_format() const { return best_texture_format_; }
66  unsigned num_resources() const { return resources_.size(); }
67
68  // Checks whether a resource is in use by a consumer.
69  bool InUseByConsumer(ResourceId id);
70
71
72  // Producer interface.
73
74  void set_default_resource_type(ResourceType type) {
75    default_resource_type_ = type;
76  }
77  ResourceType default_resource_type() const { return default_resource_type_; }
78  ResourceType GetResourceType(ResourceId id);
79
80  // Creates a resource of the default resource type.
81  ResourceId CreateResource(gfx::Size size,
82                            GLenum format,
83                            TextureUsageHint hint);
84
85  // Creates a resource which is tagged as being managed for GPU memory
86  // accounting purposes.
87  ResourceId CreateManagedResource(gfx::Size size,
88                                   GLenum format,
89                                   TextureUsageHint hint);
90
91  // You can also explicitly create a specific resource type.
92  ResourceId CreateGLTexture(gfx::Size size,
93                             GLenum format,
94                             GLenum texture_pool,
95                             TextureUsageHint hint);
96
97  ResourceId CreateBitmap(gfx::Size size);
98  // Wraps an external texture into a GL resource.
99  ResourceId CreateResourceFromExternalTexture(unsigned texture_id);
100
101  // Wraps an external texture mailbox into a GL resource.
102  ResourceId CreateResourceFromTextureMailbox(const TextureMailbox& mailbox);
103
104  void DeleteResource(ResourceId id);
105
106  // Update pixels from image, copying source_rect (in image) to dest_offset (in
107  // the resource).
108  void SetPixels(ResourceId id,
109                 const uint8_t* image,
110                 gfx::Rect image_rect,
111                 gfx::Rect source_rect,
112                 gfx::Vector2d dest_offset);
113
114  // Check upload status.
115  size_t NumBlockingUploads();
116  void MarkPendingUploadsAsNonBlocking();
117  double EstimatedUploadsPerSecond();
118  void FlushUploads();
119  void ReleaseCachedData();
120
121  // Flush all context operations, kicking uploads and ensuring ordering with
122  // respect to other contexts.
123  void Flush();
124
125  // Only flush the command buffer if supported.
126  // Returns true if the shallow flush occurred, false otherwise.
127  bool ShallowFlushIfSupported();
128
129  // Creates accounting for a child. Returns a child ID.
130  int CreateChild();
131
132  // Destroys accounting for the child, deleting all accounted resources.
133  void DestroyChild(int child);
134
135  // Gets the child->parent resource ID map.
136  const ResourceIdMap& GetChildToParentMap(int child) const;
137
138  // Prepares resources to be transfered to the parent, moving them to
139  // mailboxes and serializing meta-data into TransferableResources.
140  // Resources are not removed from the ResourceProvider, but are marked as
141  // "in use".
142  void PrepareSendToParent(const ResourceIdArray& resources,
143                           TransferableResourceArray* transferable_resources);
144
145  // Prepares resources to be transfered back to the child, moving them to
146  // mailboxes and serializing meta-data into TransferableResources.
147  // Resources are removed from the ResourceProvider. Note: the resource IDs
148  // passed are in the parent namespace and will be translated to the child
149  // namespace when returned.
150  void PrepareSendToChild(int child,
151                          const ResourceIdArray& resources,
152                          TransferableResourceArray* transferable_resources);
153
154  // Receives resources from a child, moving them from mailboxes. Resource IDs
155  // passed are in the child namespace, and will be translated to the parent
156  // namespace, added to the child->parent map.
157  // NOTE: if the sync_point is set on any TransferableResource, this will
158  // wait on it.
159  void ReceiveFromChild(
160      int child, const TransferableResourceArray& transferable_resources);
161
162  // Receives resources from the parent, moving them from mailboxes. Resource
163  // IDs passed are in the child namespace.
164  // NOTE: if the sync_point is set on any TransferableResource, this will
165  // wait on it.
166  void ReceiveFromParent(
167      const TransferableResourceArray& transferable_resources);
168
169  // Bind the given GL resource to a texture target for sampling using the
170  // specified filter for both minification and magnification. The resource
171  // must be locked for reading.
172  void BindForSampling(ResourceProvider::ResourceId resource_id,
173                       GLenum target,
174                       GLenum filter);
175
176  // The following lock classes are part of the ResourceProvider API and are
177  // needed to read and write the resource contents. The user must ensure
178  // that they only use GL locks on GL resources, etc, and this is enforced
179  // by assertions.
180  class CC_EXPORT ScopedReadLockGL {
181   public:
182    ScopedReadLockGL(ResourceProvider* resource_provider,
183                     ResourceProvider::ResourceId resource_id);
184    ~ScopedReadLockGL();
185
186    unsigned texture_id() const { return texture_id_; }
187
188   private:
189    ResourceProvider* resource_provider_;
190    ResourceProvider::ResourceId resource_id_;
191    unsigned texture_id_;
192
193    DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL);
194  };
195
196  class CC_EXPORT ScopedSamplerGL : public ScopedReadLockGL {
197   public:
198    ScopedSamplerGL(ResourceProvider* resource_provider,
199                    ResourceProvider::ResourceId resource_id,
200                    GLenum target,
201                    GLenum filter);
202
203   private:
204    DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL);
205  };
206
207  class CC_EXPORT ScopedWriteLockGL {
208   public:
209    ScopedWriteLockGL(ResourceProvider* resource_provider,
210                      ResourceProvider::ResourceId resource_id);
211    ~ScopedWriteLockGL();
212
213    unsigned texture_id() const { return texture_id_; }
214
215   private:
216    ResourceProvider* resource_provider_;
217    ResourceProvider::ResourceId resource_id_;
218    unsigned texture_id_;
219
220    DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL);
221  };
222
223  class CC_EXPORT ScopedReadLockSoftware {
224   public:
225    ScopedReadLockSoftware(ResourceProvider* resource_provider,
226                           ResourceProvider::ResourceId resource_id);
227    ~ScopedReadLockSoftware();
228
229    const SkBitmap* sk_bitmap() const { return &sk_bitmap_; }
230
231   private:
232    ResourceProvider* resource_provider_;
233    ResourceProvider::ResourceId resource_id_;
234    SkBitmap sk_bitmap_;
235
236    DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware);
237  };
238
239  class CC_EXPORT ScopedWriteLockSoftware {
240   public:
241    ScopedWriteLockSoftware(ResourceProvider* resource_provider,
242                            ResourceProvider::ResourceId resource_id);
243    ~ScopedWriteLockSoftware();
244
245    SkCanvas* sk_canvas() { return sk_canvas_.get(); }
246
247   private:
248    ResourceProvider* resource_provider_;
249    ResourceProvider::ResourceId resource_id_;
250    SkBitmap sk_bitmap_;
251    scoped_ptr<SkCanvas> sk_canvas_;
252
253    DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware);
254  };
255
256  class Fence : public base::RefCounted<Fence> {
257   public:
258    Fence() {}
259    virtual bool HasPassed() = 0;
260
261   protected:
262    friend class base::RefCounted<Fence>;
263    virtual ~Fence() {}
264
265    DISALLOW_COPY_AND_ASSIGN(Fence);
266  };
267
268  // Acquire pixel buffer for resource. The pixel buffer can be used to
269  // set resource pixels without performing unnecessary copying.
270  void AcquirePixelBuffer(ResourceId id);
271  void ReleasePixelBuffer(ResourceId id);
272
273  // Map/unmap the acquired pixel buffer.
274  uint8_t* MapPixelBuffer(ResourceId id);
275  void UnmapPixelBuffer(ResourceId id);
276
277  // Update pixels from acquired pixel buffer.
278  void SetPixelsFromBuffer(ResourceId id);
279
280  // Asynchronously update pixels from acquired pixel buffer.
281  void BeginSetPixels(ResourceId id);
282  void ForceSetPixelsToComplete(ResourceId id);
283  bool DidSetPixelsComplete(ResourceId id);
284  void AbortSetPixels(ResourceId id);
285
286  // For tests only! This prevents detecting uninitialized reads.
287  // Use SetPixels or LockForWrite to allocate implicitly.
288  void AllocateForTesting(ResourceId id);
289
290  // Sets the current read fence. If a resource is locked for read
291  // and has read fences enabled, the resource will not allow writes
292  // until this fence has passed.
293  void SetReadLockFence(scoped_refptr<Fence> fence) {
294    current_read_lock_fence_ = fence;
295  }
296  Fence* GetReadLockFence() { return current_read_lock_fence_; }
297
298  // Enable read lock fences for a specific resource.
299  void EnableReadLockFences(ResourceProvider::ResourceId id, bool enable);
300
301  // Indicates if we can currently lock this resource for write.
302  bool CanLockForWrite(ResourceId id);
303
304  cc::ContextProvider* offscreen_context_provider() {
305    return offscreen_context_provider_.get();
306  }
307  void set_offscreen_context_provider(
308      scoped_refptr<cc::ContextProvider> offscreen_context_provider) {
309    offscreen_context_provider_ = offscreen_context_provider;
310  }
311
312 private:
313  struct Resource {
314    Resource();
315    ~Resource();
316    Resource(unsigned texture_id, gfx::Size size, GLenum format, GLenum filter);
317    Resource(uint8_t* pixels, gfx::Size size, GLenum format, GLenum filter);
318
319    unsigned gl_id;
320    // Pixel buffer used for set pixels without unnecessary copying.
321    unsigned gl_pixel_buffer_id;
322    // Query used to determine when asynchronous set pixels complete.
323    unsigned gl_upload_query_id;
324    TextureMailbox mailbox;
325    uint8_t* pixels;
326    uint8_t* pixel_buffer;
327    int lock_for_read_count;
328    bool locked_for_write;
329    bool external;
330    bool exported;
331    bool marked_for_deletion;
332    bool pending_set_pixels;
333    bool set_pixels_completion_forced;
334    bool allocated;
335    bool enable_read_lock_fences;
336    scoped_refptr<Fence> read_lock_fence;
337    gfx::Size size;
338    GLenum format;
339    // TODO(skyostil): Use a separate sampler object for filter state.
340    GLenum filter;
341    ResourceType type;
342  };
343  typedef base::hash_map<ResourceId, Resource> ResourceMap;
344  struct Child {
345    Child();
346    ~Child();
347
348    ResourceIdMap child_to_parent_map;
349    ResourceIdMap parent_to_child_map;
350  };
351  typedef base::hash_map<int, Child> ChildMap;
352
353  bool ReadLockFenceHasPassed(Resource* resource) {
354    return !resource->read_lock_fence ||
355        resource->read_lock_fence->HasPassed();
356  }
357
358  explicit ResourceProvider(OutputSurface* output_surface);
359  bool Initialize();
360
361  const Resource* LockForRead(ResourceId id);
362  void UnlockForRead(ResourceId id);
363  const Resource* LockForWrite(ResourceId id);
364  void UnlockForWrite(ResourceId id);
365  static void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap,
366                                           const Resource* resource);
367
368  bool TransferResource(WebKit::WebGraphicsContext3D* context,
369                        ResourceId id,
370                        TransferableResource* resource);
371  void DeleteResourceInternal(ResourceMap::iterator it);
372  void LazyAllocate(Resource* resource);
373
374  OutputSurface* output_surface_;
375  ResourceId next_id_;
376  ResourceMap resources_;
377  int next_child_;
378  ChildMap children_;
379
380  ResourceType default_resource_type_;
381  bool use_texture_storage_ext_;
382  bool use_texture_usage_hint_;
383  bool use_shallow_flush_;
384  scoped_ptr<TextureUploader> texture_uploader_;
385  scoped_ptr<AcceleratedTextureCopier> texture_copier_;
386  int max_texture_size_;
387  GLenum best_texture_format_;
388
389  scoped_refptr<cc::ContextProvider> offscreen_context_provider_;
390
391  base::ThreadChecker thread_checker_;
392
393  scoped_refptr<Fence> current_read_lock_fence_;
394
395  DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
396};
397
398}
399
400#endif  // CC_RESOURCES_RESOURCE_PROVIDER_H_
401