summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h
blob: 9a2c289975ae692aa6a95a2dc706d05fa4238760 (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2015 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 THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_ASYNC_BLOB_CREATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_ASYNC_BLOB_CREATOR_H_

#include <memory>

#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_blob_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/image-encoders/image_encoder.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"

namespace blink {

class ExecutionContext;

constexpr const char* kSRGBImageColorSpaceName = "srgb";
constexpr const char* kRec2020ImageColorSpaceName = "rec2020";
constexpr const char* kDisplayP3ImageColorSpaceName = "display-p3";

constexpr const char* kRGBA8ImagePixelFormatName = "uint8";
constexpr const char* kRGBA16ImagePixelFormatName = "uint16";

class CORE_EXPORT CanvasAsyncBlobCreator
    : public GarbageCollected<CanvasAsyncBlobCreator> {
 public:
  // This enum is used to back an UMA histogram, and should therefore be treated
  // as append-only. Idle tasks are not implemented for some image types.
  enum IdleTaskStatus {
    kIdleTaskNotStarted = 0,
    kIdleTaskStarted = 1,
    kIdleTaskCompleted = 2,
    kIdleTaskFailed = 3,
    kIdleTaskSwitchedToImmediateTask = 4,
    kIdleTaskNotSupported = 5,
    kMaxValue = kIdleTaskNotSupported,
  };
  enum ToBlobFunctionType {
    kHTMLCanvasToBlobCallback,
    kHTMLCanvasConvertToBlobPromise,
    kOffscreenCanvasConvertToBlobPromise
  };

  void ScheduleAsyncBlobCreation(const double& quality);

  CanvasAsyncBlobCreator(scoped_refptr<StaticBitmapImage>,
                         const ImageEncodeOptions* options,
                         ToBlobFunctionType function_type,
                         base::TimeTicks start_time,
                         ExecutionContext*,
                         ScriptPromiseResolver*);
  CanvasAsyncBlobCreator(scoped_refptr<StaticBitmapImage>,
                         const ImageEncodeOptions*,
                         ToBlobFunctionType,
                         V8BlobCallback*,
                         base::TimeTicks start_time,
                         ExecutionContext*,
                         ScriptPromiseResolver* = nullptr);
  virtual ~CanvasAsyncBlobCreator();

  // Methods are virtual for mocking in unit tests
  virtual void SignalTaskSwitchInStartTimeoutEventForTesting() {}
  virtual void SignalTaskSwitchInCompleteTimeoutEventForTesting() {}

  virtual void Trace(Visitor*);

  static sk_sp<SkColorSpace> BlobColorSpaceToSkColorSpace(
      String blob_color_space);

  bool EncodeImageForConvertToBlobTest();
  Vector<unsigned char> GetEncodedImageForConvertToBlobTest() {
    return encoded_image_;
  }

 protected:
  static ImageEncodeOptions* GetImageEncodeOptionsForMimeType(
      ImageEncodingMimeType);
  // Methods are virtual for unit testing
  virtual void ScheduleInitiateEncoding(double quality);
  virtual void IdleEncodeRows(base::TimeTicks deadline);
  virtual void PostDelayedTaskToCurrentThread(const base::Location&,
                                              base::OnceClosure,
                                              double delay_ms);
  virtual void SignalAlternativeCodePathFinishedForTesting() {}
  virtual void CreateBlobAndReturnResult();
  virtual void CreateNullAndReturnResult();

  void InitiateEncoding(double quality, base::TimeTicks deadline);

 protected:
  IdleTaskStatus idle_task_status_;
  bool fail_encoder_initialization_for_test_;
  bool enforce_idle_encoding_for_test_;

 private:
  friend class CanvasAsyncBlobCreatorTest;

  void Dispose();

  scoped_refptr<StaticBitmapImage> image_;
  std::unique_ptr<ImageEncoder> encoder_;
  Vector<unsigned char> encoded_image_;
  int num_rows_completed_;
  Member<ExecutionContext> context_;

  SkPixmap src_data_;
  ImageEncodingMimeType mime_type_;
  Member<const ImageEncodeOptions> encode_options_;
  ToBlobFunctionType function_type_;
  sk_sp<SkData> png_data_helper_;

  // Chrome metrics use
  base::TimeTicks start_time_;
  base::TimeTicks schedule_idle_task_start_time_;
  bool static_bitmap_image_loaded_;

  // Used when CanvasAsyncBlobCreator runs on main thread only
  scoped_refptr<base::SingleThreadTaskRunner> parent_frame_task_runner_;

  // Used for HTMLCanvasElement only
  Member<V8BlobCallback> callback_;

  // Used for OffscreenCanvas only
  Member<ScriptPromiseResolver> script_promise_resolver_;

  bool EncodeImage(const double&);

  // PNG, JPEG
  bool InitializeEncoder(double quality);
  void ForceEncodeRowsOnCurrentThread();  // Similar to IdleEncodeRows
                                          // without deadline

  // WEBP
  void EncodeImageOnEncoderThread(double quality);

  void IdleTaskStartTimeoutEvent(double quality);
  void IdleTaskCompleteTimeoutEvent();
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_ASYNC_BLOB_CREATOR_H_