summaryrefslogtreecommitdiff
path: root/chromium/cc/tiles/image_controller.h
blob: f62638a1c078679aa09597ebc75ec3f40395c7b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_TILES_IMAGE_CONTROLLER_H_
#define CC_TILES_IMAGE_CONTROLLER_H_

#include <set>
#include <vector>

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/simple_thread.h"
#include "cc/base/cc_export.h"
#include "cc/base/unique_notifier.h"
#include "cc/playback/draw_image.h"
#include "cc/raster/tile_task.h"
#include "cc/tiles/image_decode_cache.h"

namespace cc {

class CC_EXPORT ImageController {
 public:
  enum class ImageDecodeResult { SUCCESS, DECODE_NOT_REQUIRED, FAILURE };

  using ImageDecodeRequestId = uint64_t;
  using ImageDecodedCallback =
      base::Callback<void(ImageDecodeRequestId, ImageDecodeResult)>;
  explicit ImageController(
      base::SequencedTaskRunner* origin_task_runner,
      scoped_refptr<base::SequencedTaskRunner> worker_task_runner);
  virtual ~ImageController();

  void SetImageDecodeCache(ImageDecodeCache* cache);
  void GetTasksForImagesAndRef(
      std::vector<DrawImage>* images,
      std::vector<scoped_refptr<TileTask>>* tasks,
      const ImageDecodeCache::TracingInfo& tracing_info);
  void UnrefImages(const std::vector<DrawImage>& images);
  void ReduceMemoryUsage();
  std::vector<scoped_refptr<TileTask>> SetPredecodeImages(
      std::vector<DrawImage> predecode_images,
      const ImageDecodeCache::TracingInfo& tracing_info);

  // Virtual for testing.
  virtual void UnlockImageDecode(ImageDecodeRequestId id);

  // This function requests that the given image be decoded and locked. Once the
  // callback has been issued, it is passed an ID, which should be used to
  // unlock this image. It is up to the caller to ensure that the image is later
  // unlocked using UnlockImageDecode.
  // Virtual for testing.
  virtual ImageDecodeRequestId QueueImageDecode(
      sk_sp<const SkImage> image,
      const ImageDecodedCallback& callback);

 protected:
  scoped_refptr<base::SequencedTaskRunner> worker_task_runner_;

 private:
  struct ImageDecodeRequest {
    ImageDecodeRequest();
    ImageDecodeRequest(ImageDecodeRequestId id,
                       const DrawImage& draw_image,
                       const ImageDecodedCallback& callback,
                       scoped_refptr<TileTask> task,
                       bool need_unref);
    ImageDecodeRequest(ImageDecodeRequest&& other);
    ImageDecodeRequest(const ImageDecodeRequest& other);
    ~ImageDecodeRequest();

    ImageDecodeRequest& operator=(ImageDecodeRequest&& other);
    ImageDecodeRequest& operator=(const ImageDecodeRequest& other);

    ImageDecodeRequestId id;
    DrawImage draw_image;
    ImageDecodedCallback callback;
    scoped_refptr<TileTask> task;
    bool need_unref;
  };

  void StopWorkerTasks();

  // Called from the worker thread.
  void ProcessNextImageDecodeOnWorkerThread();

  void ImageDecodeCompleted(ImageDecodeRequestId id);
  void GenerateTasksForOrphanedRequests();

  ImageDecodeCache* cache_ = nullptr;
  std::vector<DrawImage> predecode_locked_images_;

  static ImageDecodeRequestId s_next_image_decode_queue_id_;
  std::unordered_map<ImageDecodeRequestId, DrawImage> requested_locked_images_;

  base::SequencedTaskRunner* origin_task_runner_ = nullptr;

  // The variables defined below this lock (aside from weak_ptr_factory_) can
  // only be accessed when the lock is acquired.
  base::Lock lock_;
  std::map<ImageDecodeRequestId, ImageDecodeRequest> image_decode_queue_;
  std::map<ImageDecodeRequestId, ImageDecodeRequest>
      requests_needing_completion_;
  bool abort_tasks_ = false;
  // Orphaned requests are requests that were either in queue or needed a
  // completion callback when we set the decode cache to be nullptr. When a new
  // decode cache is set, these requests are re-enqueued again with tasks
  // generated by the new cache. Note that when the cache is set, then aside
  // from generating new tasks, this vector should be empty.
  std::vector<ImageDecodeRequest> orphaned_decode_requests_;

  base::WeakPtrFactory<ImageController> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ImageController);
};

}  // namespace cc

#endif  // CC_TILES_IMAGE_CONTROLLER_H_