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

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

Issue 2738573002: Streamline the presentation of ImageBitmapRenderingContext (Closed)
Patch Set: Fixed expectations Created 3 years, 8 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
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "platform/graphics/gpu/SharedGpuContext.h"
13 #include "public/platform/Platform.h"
14 #include "public/platform/WebCompositorSupport.h"
15 #include "public/platform/WebExternalTextureLayer.h"
16 #include "public/platform/WebGraphicsContext3DProvider.h"
17
18 namespace blink {
19
20 ImageLayerBridge::ImageLayerBridge(OpacityMode opacityMode)
21 : m_weakPtrFactory(this), m_opacityMode(opacityMode) {
22 m_layer =
23 Platform::current()->compositorSupport()->createExternalTextureLayer(
24 this);
25 GraphicsLayer::registerContentsLayer(m_layer->layer());
26 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
27 if (m_opacityMode == Opaque) {
28 m_layer->setOpaque(true);
29 m_layer->setBlendBackgroundColor(false);
30 }
31 }
32
33 ImageLayerBridge::~ImageLayerBridge() {
34 if (!m_disposed)
35 dispose();
36 }
37
38 void ImageLayerBridge::setImage(PassRefPtr<StaticBitmapImage> image) {
39 m_image = std::move(image);
40 if (m_image) {
41 if (m_opacityMode == NonOpaque) {
42 m_layer->setOpaque(m_image->currentFrameKnownToBeOpaque());
43 m_layer->setBlendBackgroundColor(!m_image->currentFrameKnownToBeOpaque());
44 }
45 }
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()->getTextureHandle(
54 true); // GrContext flush.
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 if (m_hasPresentedSinceLastSetImage)
79 return false;
80
81 m_hasPresentedSinceLastSetImage = true;
82
83 if (m_image->isTextureBacked()) {
84 m_image->ensureMailbox();
85 *outMailbox = cc::TextureMailbox(m_image->mailbox(), m_image->syncToken(),
86 GL_TEXTURE_2D);
87 auto func = WTF::bind(&ImageLayerBridge::mailboxReleasedGpu,
88 m_weakPtrFactory.createWeakPtr(), m_image);
89 *outReleaseCallback = cc::SingleReleaseCallback::Create(
90 convertToBaseCallback(std::move(func)));
91 } else {
92 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap();
93 if (!bitmap)
94 return false;
95
96 sk_sp<SkImage> skImage = m_image->imageForCurrentFrame();
97 if (!skImage)
98 return false;
99
100 SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(m_image->width(), 1);
101 size_t rowBytes = m_image->width() * 4;
102
103 // loop to flip Y
104 for (int row = 0; row < m_image->height(); row++) {
105 if (!skImage->readPixels(
106 dstInfo,
107 bitmap->pixels() + rowBytes * (m_image->height() - 1 - row),
108 rowBytes, 0, row))
109 return false;
110 }
111
112 *outMailbox = cc::TextureMailbox(
113 bitmap.get(), gfx::Size(m_image->width(), m_image->height()));
114 auto func = WTF::bind(&ImageLayerBridge::mailboxReleasedSoftware,
115 m_weakPtrFactory.createWeakPtr(),
116 base::Passed(&bitmap), m_image->size());
117 *outReleaseCallback = cc::SingleReleaseCallback::Create(
118 convertToBaseCallback(std::move(func)));
119 }
120
121 outMailbox->set_nearest_neighbor(m_filterQuality == kNone_SkFilterQuality);
122 // TODO(junov): Figure out how to get the color space info.
123 // outMailbox->set_color_space();
124
125 return true;
126 }
127
128 std::unique_ptr<cc::SharedBitmap> ImageLayerBridge::createOrRecycleBitmap() {
129 auto it = std::remove_if(m_recycledBitmaps.begin(), m_recycledBitmaps.end(),
130 [this](const RecycledBitmap& bitmap) {
131 return bitmap.size != m_image->size();
132 });
133 m_recycledBitmaps.shrink(it - m_recycledBitmaps.begin());
134
135 if (!m_recycledBitmaps.isEmpty()) {
136 RecycledBitmap recycled = std::move(m_recycledBitmaps.back());
137 m_recycledBitmaps.pop_back();
138 DCHECK(recycled.size == m_image->size());
139 return std::move(recycled.bitmap);
140 }
141 return Platform::current()->allocateSharedBitmap(m_image->size());
142 }
143
144 void ImageLayerBridge::mailboxReleasedGpu(RefPtr<StaticBitmapImage> image,
145 const gpu::SyncToken& token,
146 bool lostResource) {
147 if (image) {
148 DCHECK(image->isTextureBacked());
149 if (token.HasData()) {
150 if (image->hasMailbox()) {
151 image->updateSyncToken(token);
152 } else {
153 // Wait on sync token now because SkiaTextureHolder does not know
154 // about sync tokens.
155 gpu::gles2::GLES2Interface* sharedGL = SharedGpuContext::gl();
156 if (sharedGL)
157 sharedGL->WaitSyncTokenCHROMIUM(token.GetConstData());
158 }
159 }
160 }
161 // let 'image' go out of scope to finalize the release. The
162 // destructor will wait on sync token before deleting resource.
163 }
164
165 void ImageLayerBridge::mailboxReleasedSoftware(
166 std::unique_ptr<cc::SharedBitmap> bitmap,
167 const IntSize& size,
168 const gpu::SyncToken& syncToken,
169 bool lostResource) {
170 DCHECK(!syncToken.HasData()); // No sync tokens for software resources.
171 if (!m_disposed && !lostResource) {
172 RecycledBitmap recycled = {std::move(bitmap), size};
173 m_recycledBitmaps.push_back(std::move(recycled));
174 }
175 }
176
177 WebLayer* ImageLayerBridge::platformLayer() const {
178 return m_layer->layer();
179 }
180
181 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/ImageLayerBridge.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698