| OLD | NEW |
| (Empty) |
| 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_RESOURCE_PROVIDER_H_ | |
| 6 #define CC_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/texture_mailbox.h" | |
| 23 #include "cc/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 | |
| 29 namespace WebKit { | |
| 30 class WebGraphicsContext3D; | |
| 31 } | |
| 32 | |
| 33 namespace gfx { | |
| 34 class Rect; | |
| 35 class Vector2d; | |
| 36 } | |
| 37 | |
| 38 namespace cc { | |
| 39 class 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). | |
| 43 class 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_RESOURCE_PROVIDER_H_ | |
| OLD | NEW |