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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.cpp

Issue 2738573002: Streamline the presentation of ImageBitmapRenderingContext (Closed)
Patch Set: Created 3 years, 9 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 "platform/graphics/gpu/ImageLayerBridge.h"
6
7 #include "cc/resources/shared_bitmap.h"
8 #include "cc/resources/texture_mailbox.h"
9 #include "gpu/command_buffer/client/gles2_interface.h"
10 #include "platform/graphics/ColorBehavior.h"
11 #include "platform/graphics/GraphicsLayer.h"
12 #include "public/platform/Platform.h"
13 #include "public/platform/WebCompositorSupport.h"
14 #include "public/platform/WebExternalTextureLayer.h"
15
16 namespace blink {
17
18 ImageLayerBridge::ImageLayerBridge(OpacityMode opacityMode)
19 : m_weakPtrFactory(this), m_opacityMode(opacityMode) {}
20
21 ImageLayerBridge::~ImageLayerBridge() {
22 if (!m_disposed)
23 dispose();
24 }
25
26 void ImageLayerBridge::setImage(PassRefPtr<StaticBitmapImage> image) {
27 if (!m_layer) {
28 m_layer =
29 Platform::current()->compositorSupport()->createExternalTextureLayer(
30 this);
31 GraphicsLayer::registerContentsLayer(m_layer->layer());
32 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
33 if (m_opacityMode == Opaque) {
34 m_layer->setOpaque(true);
35 m_layer->setBlendBackgroundColor(false);
xlai (Olivia) 2017/03/09 21:57:27 Do you need to consider the "premultiplied alpha"
Justin Novosad 2017/03/10 21:09:59 Turns out I don't. Premul is assumed here. FWIW,
36 }
37 }
38 m_image = std::move(image);
39 if (m_image) {
40 if (m_opacityMode == NonOpaque) {
41 m_layer->setOpaque(m_image->currentFrameKnownToBeOpaque());
42 m_layer->setBlendBackgroundColor(!m_image->currentFrameKnownToBeOpaque());
43 }
44 }
45 m_layer->layer()->invalidate();
46 if (!m_hasPresentedSinceLastSetImage && m_image &&
47 m_image->isTextureBacked()) {
48 // If the layer bridge is not presenting, the GrContext may not be getting
49 // flushed regularly. The flush is normally triggered inside the
50 // m_image->ensureMailbox() call of
51 // ImageLayerBridge::PrepareTextureMailbox. To prevent a potential memory
52 // leak we must flush the GrContext here.
53 m_image->imageForCurrentFrame(ColorBehavior::tag())
54 ->getTextureHandle(true); // triggers a GrContext flush if needed.
55 }
56 m_hasPresentedSinceLastSetImage = false;
57 }
58
59 void ImageLayerBridge::dispose() {
60 if (m_layer) {
61 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
62 m_layer->clearTexture();
63 m_layer.reset();
64 }
65 m_image = nullptr;
66 m_disposed = true;
67 }
68
69 bool ImageLayerBridge::PrepareTextureMailbox(
70 cc::TextureMailbox* outMailbox,
71 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) {
72 if (m_disposed)
73 return false;
74
75 if (!m_image)
76 return false;
77
78 m_hasPresentedSinceLastSetImage = true;
79
80 if (m_image->isAccelerated()) {
81 m_image->ensureMailbox();
82 *outMailbox = cc::TextureMailbox(m_image->mailbox(), m_image->syncToken(),
83 GL_TEXTURE_2D);
84 auto func = WTF::bind(&ImageLayerBridge::mailboxReleasedGpu,
85 m_weakPtrFactory.createWeakPtr(), m_image);
86 *outReleaseCallback = cc::SingleReleaseCallback::Create(
87 convertToBaseCallback(std::move(func)));
88 } else {
89 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap();
90 if (!bitmap)
91 return false;
92
93 sk_sp<SkImage> skImage =
94 m_image->imageForCurrentFrame(ColorBehavior::tag());
95 if (!skImage)
96 return false;
97
98 SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(m_image->width(), 1);
99 size_t rowBytes = m_image->width() * 4;
100
101 // loop to flip Y
102 for (int row = 0; row < m_image->height(); row++) {
xlai (Olivia) 2017/03/09 21:57:27 Why do you do this loop? The source (x, y) seems t
Justin Novosad 2017/03/10 21:09:59 This is to do a y-flip on the image data. For som
103 if (!skImage->readPixels(
104 dstInfo,
105 bitmap->pixels() + rowBytes * (m_image->height() - 1 - row),
106 rowBytes, 0, row))
107 return false;
108 }
109
110 *outMailbox = cc::TextureMailbox(
111 bitmap.get(), gfx::Size(m_image->width(), m_image->height()));
112 auto func = WTF::bind(&ImageLayerBridge::mailboxReleasedSoftware,
113 m_weakPtrFactory.createWeakPtr(),
114 base::Passed(&bitmap), m_image->size());
115 *outReleaseCallback = cc::SingleReleaseCallback::Create(
116 convertToBaseCallback(std::move(func)));
117 }
118
119 outMailbox->set_nearest_neighbor(m_filterQuality == kNone_SkFilterQuality);
120 // TODO(junov): Figure out how to get the color space info.
121 // outMailbox->set_color_space();
122
123 return true;
124 }
125
126 std::unique_ptr<cc::SharedBitmap> ImageLayerBridge::createOrRecycleBitmap() {
127 auto it = std::remove_if(m_recycledBitmaps.begin(), m_recycledBitmaps.end(),
128 [this](const RecycledBitmap& bitmap) {
129 return bitmap.size != m_image->size();
130 });
131 m_recycledBitmaps.shrink(it - m_recycledBitmaps.begin());
132
133 if (!m_recycledBitmaps.isEmpty()) {
134 RecycledBitmap recycled = std::move(m_recycledBitmaps.back());
135 m_recycledBitmaps.pop_back();
136 DCHECK(recycled.size == m_image->size());
137 return std::move(recycled.bitmap);
138 }
139 return Platform::current()->allocateSharedBitmap(m_image->size());
140 }
141
142 void ImageLayerBridge::mailboxReleasedGpu(RefPtr<StaticBitmapImage> image,
143 const gpu::SyncToken& token,
144 bool lostResource) {
145 if (image) {
146 DCHECK(image->isAccelerated());
147 DCHECK(image->hasMailbox());
148 if (token.HasData()) {
149 image->updateSyncToken(token);
150 }
151 }
152 // let 'image' go out of scope to finalize the release. The
153 // destructor will wait on sync token before deleting resource.
154 }
155
156 void ImageLayerBridge::mailboxReleasedSoftware(
157 std::unique_ptr<cc::SharedBitmap> bitmap,
158 const IntSize& size,
159 const gpu::SyncToken& syncToken,
160 bool lostResource) {
161 DCHECK(!syncToken.HasData()); // No sync tokens for software resources.
162 if (!m_disposed && !lostResource) {
163 RecycledBitmap recycled = {std::move(bitmap), size};
164 m_recycledBitmaps.push_back(std::move(recycled));
165 }
166 }
167
168 WebLayer* ImageLayerBridge::platformLayer() const {
169 return m_layer->layer();
170 }
171
172 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698