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