summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
blob: 2b04e04828164896715abaef108d3568822a222b (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ACCELERATED_STATIC_BITMAP_IMAGE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_ACCELERATED_STATIC_BITMAP_IMAGE_H_

#include <memory>

#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"

struct SkImageInfo;

namespace viz {
class SingleReleaseCallback;
}  // namespace viz

namespace blink {
class WebGraphicsContext3DProviderWrapper;

class PLATFORM_EXPORT AcceleratedStaticBitmapImage final
    : public StaticBitmapImage {
 public:
  ~AcceleratedStaticBitmapImage() override;

  // Creates an image wrapping a shared image mailbox.
  //
  // |sync_token| is the token that must be waited on before reading the
  // contents of this mailbox.
  //
  // |shared_image_texture_id| is an optional texture bound to the shared image
  // mailbox imported into the provided context. If provided the caller must
  // ensure that the texture is bound to the shared image mailbox, stays alive
  // and has a read lock on the shared image until the |release_callback| is
  // invoked.
  //
  // |sk_image_info| provides the metadata associated with the backing.
  //
  // |texture_target| is the target that the texture should be bound to if the
  // backing is used with GL.
  //
  // |is_origin_top_left| indicates whether the origin in texture space
  // corresponds to the top-left content pixel.
  //
  // |context_provider| is the context that the mailbox was created with.
  // |context_thread_ref| and |context_task_runner| refer to the thread the
  // context is bound to. If the image is created on a different thread than
  // |context_thread_ref| then the provided sync_token must be verified and no
  // |shared_image_texture_id| should be provided.
  //
  // |release_callback| is a callback to be invoked when this mailbox can be
  // safely destroyed. It is guaranteed to be invoked on the context thread.
  //
  // Note that it is assumed that the mailbox can only be used for read
  // operations, no writes are allowed.
  static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromCanvasMailbox(
      const gpu::Mailbox&,
      const gpu::SyncToken&,
      GLuint shared_image_texture_id,
      const SkImageInfo& sk_image_info,
      GLenum texture_target,
      bool is_origin_top_left,
      base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
      base::PlatformThreadRef context_thread_ref,
      scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
      std::unique_ptr<viz::SingleReleaseCallback> release_callback);

  bool CurrentFrameKnownToBeOpaque() override;
  IntSize Size() const override;
  bool IsTextureBacked() const override { return true; }
  scoped_refptr<StaticBitmapImage> ConvertToColorSpace(sk_sp<SkColorSpace>,
                                                       SkColorType) override;

  void Draw(cc::PaintCanvas*,
            const cc::PaintFlags&,
            const FloatRect& dst_rect,
            const FloatRect& src_rect,
            RespectImageOrientationEnum,
            ImageClampingMode,
            ImageDecodingMode) override;

  bool IsValid() const final;
  WebGraphicsContext3DProvider* ContextProvider() const final;
  base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper()
      const final;
  scoped_refptr<StaticBitmapImage> MakeUnaccelerated() final;

  bool CopyToTexture(gpu::gles2::GLES2Interface* dest_gl,
                     GLenum dest_target,
                     GLuint dest_texture_id,
                     GLint dest_level,
                     bool unpack_premultiply_alpha,
                     bool unpack_flip_y,
                     const IntPoint& dest_point,
                     const IntRect& source_sub_rectangle) override;
  // To be called on sender thread before performing a transfer to a different
  // thread.
  void Transfer() final;

  // Makes sure that the sync token associated with this mailbox is verified.
  void EnsureSyncTokenVerified() final;

  // Updates the sync token that must be waited on before recycling or deleting
  // the mailbox for this image. This must be set by callers using the mailbox
  // externally to this class.
  void UpdateSyncToken(const gpu::SyncToken& sync_token) final {
    mailbox_ref_->set_sync_token(sync_token);
  }

  // Provides the mailbox backing for this image. The caller must wait on the
  // sync token before accessing this mailbox.
  gpu::MailboxHolder GetMailboxHolder() const final;
  bool IsOriginTopLeft() const final { return is_origin_top_left_; }

  PaintImage PaintImageForCurrentFrame() override;

 private:
  class MailboxRef : public ThreadSafeRefCounted<MailboxRef> {
   public:
    MailboxRef(const gpu::SyncToken& sync_token,
               base::PlatformThreadRef context_thread_ref,
               scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
               std::unique_ptr<viz::SingleReleaseCallback> release_callback);
    ~MailboxRef();

    bool is_cross_thread() const {
      return base::PlatformThread::CurrentRef() != context_thread_ref_;
    }
    void set_sync_token(gpu::SyncToken token) { sync_token_ = token; }
    const gpu::SyncToken& GetOrCreateSyncToken(
        base::WeakPtr<WebGraphicsContext3DProviderWrapper>);
    bool verified_flush() { return sync_token_.verified_flush(); }

   private:
    gpu::SyncToken sync_token_;
    const base::PlatformThreadRef context_thread_ref_;
    const scoped_refptr<base::SingleThreadTaskRunner> context_task_runner_;
    std::unique_ptr<viz::SingleReleaseCallback> release_callback_;
  };

  struct ReleaseContext {
    scoped_refptr<MailboxRef> mailbox_ref;
    GLuint texture_id = 0u;
    base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper;
  };

  static void ReleaseTexture(void* ctx);

  AcceleratedStaticBitmapImage(
      const gpu::Mailbox&,
      const gpu::SyncToken&,
      GLuint shared_image_texture_id,
      const SkImageInfo& sk_image_info,
      GLenum texture_target,
      bool is_origin_top_left,
      const ImageOrientation& orientation,
      base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
      base::PlatformThreadRef context_thread_ref,
      scoped_refptr<base::SingleThreadTaskRunner> context_task_runner,
      std::unique_ptr<viz::SingleReleaseCallback> release_callback);

  void CreateImageFromMailboxIfNeeded();
  void InitializeSkImage(GLuint shared_image_texture_id);

  const gpu::Mailbox mailbox_;
  const SkImageInfo sk_image_info_;
  const GLenum texture_target_;
  const bool is_origin_top_left_;

  base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
  scoped_refptr<MailboxRef> mailbox_ref_;

  // The context this SkImage is bound to.
  base::WeakPtr<WebGraphicsContext3DProviderWrapper>
      skia_context_provider_wrapper_;
  sk_sp<SkImage> sk_image_;

  PaintImage::ContentId paint_image_content_id_;
  THREAD_CHECKER(thread_checker_);
};

}  // namespace blink

#endif