Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3188)

Unified Diff: cc/tiles/gpu_image_decode_controller.h

Issue 1832573004: Gpu Image Decode Controller (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/resources/resource_format.cc ('k') | cc/tiles/gpu_image_decode_controller.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/tiles/gpu_image_decode_controller.h
diff --git a/cc/tiles/gpu_image_decode_controller.h b/cc/tiles/gpu_image_decode_controller.h
index 390ef8ed972cbdc45ccc59cc5efe79c194edbc9f..10b03e136cccfcdbb802f4386d686f208819e8dd 100644
--- a/cc/tiles/gpu_image_decode_controller.h
+++ b/cc/tiles/gpu_image_decode_controller.h
@@ -5,21 +5,60 @@
#ifndef CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
#define CC_TILES_GPU_IMAGE_DECODE_CONTROLLER_H_
+#include <memory>
#include <unordered_map>
-#include <unordered_set>
+#include <vector>
+#include "base/containers/mru_cache.h"
+#include "base/memory/discardable_memory.h"
#include "base/synchronization/lock.h"
+#include "base/trace_event/memory_dump_provider.h"
#include "cc/base/cc_export.h"
+#include "cc/resources/resource_format.h"
#include "cc/tiles/image_decode_controller.h"
+#include "skia/ext/refptr.h"
+
+class SkImageTextureData;
namespace cc {
+class ContextProvider;
+
+// GpuImageDecodeController handles the decode and upload of images that will
+// be used by Skia's GPU raster path. It also maintains a cache of these
+// decoded/uploaded images for later re-use.
+//
+// Generally, when an image is required for raster, GpuImageDecodeController
+// creates two tasks, one to decode the image, and one to upload the image to
+// the GPU. These tasks are completed before the raster task which depends on
+// the image. We need to seperate decode and upload tasks, as decode can occur
+// simultaneously on multiple threads, while upload requires the GL context
+// lock must happen on our non-concurrent raster thread.
+//
+// Decoded and Uploaded image data share a single cache entry. Depending on how
+// far we've progressed, this cache entry may contain CPU-side decoded data,
+// GPU-side uploaded data, or both. Because CPU-side decoded data is stored in
+// discardable memory, and is only locked for short periods of time (until the
+// upload completes), this memory is not counted against our sized cache
+// limits. Uploaded GPU memory, being non-discardable, always counts against
+// our limits.
+//
+// In cases where the number of images needed exceeds our cache limits, we
+// operate in an "at-raster" mode. In this mode, there are no decode/upload
+// tasks, and images are decoded/uploaded as needed, immediately before being
+// used in raster. Cache entries for at-raster tasks are marked as such, which
+// prevents future tasks from taking a dependency on them and extending their
+// lifetime longer than is necessary.
class CC_EXPORT GpuImageDecodeController : public ImageDecodeController {
public:
- GpuImageDecodeController();
+ explicit GpuImageDecodeController(ContextProvider* context,
+ ResourceFormat decode_format);
~GpuImageDecodeController() override;
// ImageDecodeController overrides.
+
+ // Finds the existing uploaded image for the provided DrawImage. Creates an
+ // upload task to upload the image if an exsiting image does not exist.
bool GetTaskForImageAndRef(const DrawImage& image,
uint64_t prepare_tiles_id,
scoped_refptr<ImageDecodeTask>* task) override;
@@ -28,17 +67,124 @@ class CC_EXPORT GpuImageDecodeController : public ImageDecodeController {
void DrawWithImageFinished(const DrawImage& image,
const DecodedDrawImage& decoded_image) override;
void ReduceCacheUsage() override;
+ void SetShouldAggressivelyFreeResources(
+ bool aggressively_free_resources) override;
+ // Called by Decode / Upload tasks.
void DecodeImage(const DrawImage& image);
+ void UploadImage(const DrawImage& image);
+ void DecodeTaskCompleted(const DrawImage& image);
+ void UploadTaskCompleted(const DrawImage& image);
- void RemovePendingTaskForImage(const DrawImage& image);
+ // For testing only.
+ void SetCachedItemLimitForTesting(size_t limit) {
+ cached_items_limit_ = limit;
+ }
+ void SetCachedBytesLimitForTesting(size_t limit) {
+ cached_bytes_limit_ = limit;
+ }
+ size_t GetBytesUsedForTesting() const { return bytes_used_; }
private:
+ enum class DecodedDataMode { GPU, CPU };
+
+ // Stores the CPU-side decoded bits of an image and supporting fields.
+ struct DecodedImageData {
+ DecodedImageData();
+ ~DecodedImageData();
+
+ // May be null if image not yet decoded.
+ std::unique_ptr<base::DiscardableMemory> data;
+ uint32_t ref_count;
+ bool is_locked;
+
+ // Set to true if the image was corrupt and could not be decoded.
+ bool decode_failure;
+ };
+
+ // Stores the GPU-side image and supporting fields.
+ struct UploadedImageData {
+ UploadedImageData();
+ ~UploadedImageData();
+
+ // May be null if image not yet uploaded / prepared.
+ skia::RefPtr<SkImage> image;
+ // True if the image is counting against our memory limits.
+ bool budgeted;
+ uint32_t ref_count;
+ };
+
+ struct ImageData {
+ ImageData(DecodedDataMode mode, size_t size);
+ ~ImageData();
+
+ const DecodedDataMode mode;
+ const size_t size;
+ bool is_at_raster;
+
+ DecodedImageData decode;
+ UploadedImageData upload;
+ };
+
+ using ImageDataMRUCache =
+ base::MRUCache<uint32_t, std::unique_ptr<ImageData>>;
+
+ // All private functions should only be called while holding |lock_|. Some
+ // functions also require the |context_| lock. These are indicated by
+ // additional comments.
+
+ // Similar to GetTaskForImageAndRef, but gets the dependent decode task
+ // rather than the upload task, if necessary.
+ scoped_refptr<ImageDecodeTask> GetImageDecodeTaskAndRef(
+ const DrawImage& image,
+ uint64_t prepare_tiles_id);
+
+ void RefImageDecode(const DrawImage& draw_image);
+ void UnrefImageDecode(const DrawImage& draw_image);
+ void RefImage(const DrawImage& draw_image);
+ void UnrefImageInternal(const DrawImage& draw_image);
+ void RefCountChanged(ImageData* image_data);
+
+ // Ensures that the cache can hold an element of |required_size|, freeing
+ // unreferenced cache entries if necessary to make room.
+ bool EnsureCapacity(size_t required_size);
+ bool CanFitSize(size_t size) const;
+ bool ExceedsPreferredCount() const;
+
+ void DecodeImageIfNecessary(const DrawImage& draw_image,
+ ImageData* image_data);
+
+ std::unique_ptr<GpuImageDecodeController::ImageData> CreateImageData(
+ const DrawImage& image);
+ SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image) const;
+
+ // The following two functions also require the |context_| lock to be held.
+ void UploadImageIfNecessary(const DrawImage& draw_image,
+ ImageData* image_data);
+ void DeletePendingImages();
+
+ const ResourceFormat format_;
+ ContextProvider* context_;
+ skia::RefPtr<GrContextThreadSafeProxy> context_threadsafe_proxy_;
+
+ // All members below this point must only be accessed while holding |lock_|.
base::Lock lock_;
- std::unordered_set<uint32_t> prerolled_images_;
std::unordered_map<uint32_t, scoped_refptr<ImageDecodeTask>>
- pending_image_tasks_;
+ pending_image_upload_tasks_;
+ std::unordered_map<uint32_t, scoped_refptr<ImageDecodeTask>>
+ pending_image_decode_tasks_;
+
+ ImageDataMRUCache image_data_;
+
+ size_t cached_items_limit_;
+ size_t cached_bytes_limit_;
+ size_t bytes_used_;
+
+ // We can't release GPU backed SkImages without holding the context lock,
+ // so we add them to this list and defer deletion until the next time the lock
+ // is held.
+ std::vector<skia::RefPtr<SkImage>> images_pending_deletion_;
};
} // namespace cc
« no previous file with comments | « cc/resources/resource_format.cc ('k') | cc/tiles/gpu_image_decode_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698