1 // Copyright 2016 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 #include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
6 
7 #include "components/viz/common/gpu/context_provider.h"
8 #include "third_party/blink/public/platform/platform.h"
9 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
10 #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
11 #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h"
12 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
13 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
14 #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
15 #include "third_party/skia/include/core/SkImage.h"
16 
17 namespace blink {
18 
19 scoped_refptr<UnacceleratedStaticBitmapImage>
Create(sk_sp<SkImage> image,ImageOrientation orientation)20 UnacceleratedStaticBitmapImage::Create(sk_sp<SkImage> image,
21                                        ImageOrientation orientation) {
22   DCHECK(!image->isTextureBacked());
23   return base::AdoptRef(
24       new UnacceleratedStaticBitmapImage(std::move(image), orientation));
25 }
26 
UnacceleratedStaticBitmapImage(sk_sp<SkImage> image,ImageOrientation orientation)27 UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(
28     sk_sp<SkImage> image,
29     ImageOrientation orientation)
30     : StaticBitmapImage(orientation) {
31   CHECK(image);
32   DCHECK(!image->isLazyGenerated());
33   paint_image_ =
34       CreatePaintImageBuilder()
35           .set_image(std::move(image), cc::PaintImage::GetNextContentId())
36           .TakePaintImage();
37 }
38 
39 scoped_refptr<UnacceleratedStaticBitmapImage>
Create(PaintImage image,ImageOrientation orientation)40 UnacceleratedStaticBitmapImage::Create(PaintImage image,
41                                        ImageOrientation orientation) {
42   return base::AdoptRef(
43       new UnacceleratedStaticBitmapImage(std::move(image), orientation));
44 }
45 
UnacceleratedStaticBitmapImage(PaintImage image,ImageOrientation orientation)46 UnacceleratedStaticBitmapImage::UnacceleratedStaticBitmapImage(
47     PaintImage image,
48     ImageOrientation orientation)
49     : StaticBitmapImage(orientation), paint_image_(std::move(image)) {
50   CHECK(paint_image_.GetSkImage());
51 }
52 
~UnacceleratedStaticBitmapImage()53 UnacceleratedStaticBitmapImage::~UnacceleratedStaticBitmapImage() {
54   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
55   if (!original_skia_image_)
56     return;
57 
58   if (!original_skia_image_task_runner_->BelongsToCurrentThread()) {
59     PostCrossThreadTask(
60         *original_skia_image_task_runner_, FROM_HERE,
61         CrossThreadBindOnce([](sk_sp<SkImage> image) { image.reset(); },
62                             std::move(original_skia_image_)));
63   } else {
64     original_skia_image_.reset();
65   }
66 }
67 
Size() const68 IntSize UnacceleratedStaticBitmapImage::Size() const {
69   return IntSize(paint_image_.width(), paint_image_.height());
70 }
71 
IsPremultiplied() const72 bool UnacceleratedStaticBitmapImage::IsPremultiplied() const {
73   return paint_image_.GetSkImage()->alphaType() ==
74          SkAlphaType::kPremul_SkAlphaType;
75 }
76 
CurrentFrameKnownToBeOpaque()77 bool UnacceleratedStaticBitmapImage::CurrentFrameKnownToBeOpaque() {
78   return paint_image_.GetSkImage()->isOpaque();
79 }
80 
Draw(cc::PaintCanvas * canvas,const cc::PaintFlags & flags,const FloatRect & dst_rect,const FloatRect & src_rect,RespectImageOrientationEnum should_respect_image_orientation,ImageClampingMode clamp_mode,ImageDecodingMode)81 void UnacceleratedStaticBitmapImage::Draw(
82     cc::PaintCanvas* canvas,
83     const cc::PaintFlags& flags,
84     const FloatRect& dst_rect,
85     const FloatRect& src_rect,
86     RespectImageOrientationEnum should_respect_image_orientation,
87     ImageClampingMode clamp_mode,
88     ImageDecodingMode) {
89   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
90   StaticBitmapImage::DrawHelper(canvas, flags, dst_rect, src_rect, clamp_mode,
91                                 should_respect_image_orientation,
92                                 PaintImageForCurrentFrame());
93 }
94 
PaintImageForCurrentFrame()95 PaintImage UnacceleratedStaticBitmapImage::PaintImageForCurrentFrame() {
96   return paint_image_;
97 }
98 
Transfer()99 void UnacceleratedStaticBitmapImage::Transfer() {
100   DETACH_FROM_THREAD(thread_checker_);
101 
102   original_skia_image_ = paint_image_.GetSkImage();
103   original_skia_image_task_runner_ = Thread::Current()->GetTaskRunner();
104 }
105 
106 scoped_refptr<StaticBitmapImage>
ConvertToColorSpace(sk_sp<SkColorSpace> color_space,SkColorType color_type)107 UnacceleratedStaticBitmapImage::ConvertToColorSpace(
108     sk_sp<SkColorSpace> color_space,
109     SkColorType color_type) {
110   DCHECK(color_space);
111 
112   sk_sp<SkImage> skia_image = PaintImageForCurrentFrame().GetSkImage();
113   // If we don't need to change the color type, use SkImage::makeColorSpace()
114   if (skia_image->colorType() == color_type) {
115     skia_image = skia_image->makeColorSpace(color_space);
116   } else {
117     skia_image =
118         skia_image->makeColorTypeAndColorSpace(color_type, color_space);
119   }
120   return UnacceleratedStaticBitmapImage::Create(skia_image, orientation_);
121 }
122 
123 }  // namespace blink
124