| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/graphics/OffscreenCanvasFrameDispatcherImpl.h" | 5 #include "platform/graphics/OffscreenCanvasFrameDispatcherImpl.h" |
| 6 | 6 |
| 7 #include "cc/output/compositor_frame.h" | 7 #include "cc/output/compositor_frame.h" |
| 8 #include "cc/output/delegated_frame_data.h" | 8 #include "cc/output/delegated_frame_data.h" |
| 9 #include "cc/quads/render_pass.h" | 9 #include "cc/quads/render_pass.h" |
| 10 #include "cc/quads/shared_quad_state.h" | 10 #include "cc/quads/shared_quad_state.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 m_binding(this) { | 45 m_binding(this) { |
| 46 DCHECK(!m_sink.is_bound()); | 46 DCHECK(!m_sink.is_bound()); |
| 47 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; | 47 mojom::blink::OffscreenCanvasCompositorFrameSinkProviderPtr provider; |
| 48 Platform::current()->interfaceProvider()->getInterface( | 48 Platform::current()->interfaceProvider()->getInterface( |
| 49 mojo::GetProxy(&provider)); | 49 mojo::GetProxy(&provider)); |
| 50 provider->CreateCompositorFrameSink(m_surfaceId, | 50 provider->CreateCompositorFrameSink(m_surfaceId, |
| 51 m_binding.CreateInterfacePtrAndBind(), | 51 m_binding.CreateInterfacePtrAndBind(), |
| 52 mojo::GetProxy(&m_sink)); | 52 mojo::GetProxy(&m_sink)); |
| 53 } | 53 } |
| 54 | 54 |
| 55 // Case 1: both canvas and compositor are not gpu accelerated. | 55 // Case 1: both canvas and compositor are not gpu accelerated, or canvas is |
| 56 // accelerated but --disable-gpu-compositing is specified, or |
| 57 // WebGL's commit called with swiftshader. The last case is indicated by |
| 58 // WebGraphicsContext3DProvider::isSoftwareRendering. |
| 56 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceInMemory( | 59 void OffscreenCanvasFrameDispatcherImpl::setTransferableResourceInMemory( |
| 57 cc::TransferableResource& resource, | 60 cc::TransferableResource& resource, |
| 58 RefPtr<StaticBitmapImage> image) { | 61 RefPtr<StaticBitmapImage> image) { |
| 59 std::unique_ptr<cc::SharedBitmap> bitmap = | 62 std::unique_ptr<cc::SharedBitmap> bitmap = |
| 60 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); | 63 Platform::current()->allocateSharedBitmap(IntSize(m_width, m_height)); |
| 61 if (!bitmap) | 64 if (!bitmap) |
| 62 return; | 65 return; |
| 63 unsigned char* pixels = bitmap->pixels(); | 66 unsigned char* pixels = bitmap->pixels(); |
| 64 DCHECK(pixels); | 67 DCHECK(pixels); |
| 65 SkImageInfo imageInfo = SkImageInfo::Make( | 68 SkImageInfo imageInfo = SkImageInfo::Make( |
| 66 m_width, m_height, kN32_SkColorType, | 69 m_width, m_height, kN32_SkColorType, |
| 67 image->isPremultiplied() ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); | 70 image->isPremultiplied() ? kPremul_SkAlphaType : kUnpremul_SkAlphaType); |
| 68 // TODO(xlai): Optimize to avoid copying pixels. See crbug.com/651456. | 71 // TODO(xlai): Optimize to avoid copying pixels. See crbug.com/651456. |
| 72 // However, in the case when |image| is texture backed, this function call |
| 73 // does a GPU readback which is required. |
| 69 image->imageForCurrentFrame()->readPixels(imageInfo, pixels, | 74 image->imageForCurrentFrame()->readPixels(imageInfo, pixels, |
| 70 imageInfo.minRowBytes(), 0, 0); | 75 imageInfo.minRowBytes(), 0, 0); |
| 71 resource.mailbox_holder.mailbox = bitmap->id(); | 76 resource.mailbox_holder.mailbox = bitmap->id(); |
| 72 resource.mailbox_holder.texture_target = 0; | 77 resource.mailbox_holder.texture_target = 0; |
| 73 resource.is_software = true; | 78 resource.is_software = true; |
| 74 | 79 |
| 75 // Hold ref to |bitmap|, to keep it alive until the browser ReturnResources. | 80 // Hold ref to |bitmap|, to keep it alive until the browser ReturnResources. |
| 76 // It guarantees that the shared bitmap is not re-used or deleted. | 81 // It guarantees that the shared bitmap is not re-used or deleted. |
| 77 m_sharedBitmaps.add(m_nextResourceId, std::move(bitmap)); | 82 m_sharedBitmaps.add(m_nextResourceId, std::move(bitmap)); |
| 78 } | 83 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 resource.mailbox_holder = gpu::MailboxHolder( | 147 resource.mailbox_holder = gpu::MailboxHolder( |
| 143 image->getMailbox(), image->getSyncToken(), GL_TEXTURE_2D); | 148 image->getMailbox(), image->getSyncToken(), GL_TEXTURE_2D); |
| 144 resource.read_lock_fences_enabled = false; | 149 resource.read_lock_fences_enabled = false; |
| 145 resource.is_software = false; | 150 resource.is_software = false; |
| 146 | 151 |
| 147 // Hold ref to |image|, to keep it alive until the browser ReturnResources. | 152 // Hold ref to |image|, to keep it alive until the browser ReturnResources. |
| 148 // It guarantees that the resource is not re-used or deleted. | 153 // It guarantees that the resource is not re-used or deleted. |
| 149 m_cachedImages.add(m_nextResourceId, std::move(image)); | 154 m_cachedImages.add(m_nextResourceId, std::move(image)); |
| 150 } | 155 } |
| 151 | 156 |
| 157 // When WebGL's commit is called on SwiftShader, we have software rendered |
| 158 // WebGL. |
| 152 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( | 159 void OffscreenCanvasFrameDispatcherImpl::dispatchFrame( |
| 153 RefPtr<StaticBitmapImage> image) { | 160 RefPtr<StaticBitmapImage> image, |
| 161 bool isWebGLSoftwareRendering) { |
| 154 if (!image) | 162 if (!image) |
| 155 return; | 163 return; |
| 156 if (!verifyImageSize(image->imageForCurrentFrame())) | 164 if (!verifyImageSize(image->imageForCurrentFrame())) |
| 157 return; | 165 return; |
| 158 cc::CompositorFrame frame; | 166 cc::CompositorFrame frame; |
| 167 // TODO(crbug.com/652931): update the device_scale_factor |
| 159 frame.metadata.device_scale_factor = 1.0f; | 168 frame.metadata.device_scale_factor = 1.0f; |
| 160 frame.delegated_frame_data.reset(new cc::DelegatedFrameData); | 169 frame.delegated_frame_data.reset(new cc::DelegatedFrameData); |
| 161 | 170 |
| 162 const gfx::Rect bounds(m_width, m_height); | 171 const gfx::Rect bounds(m_width, m_height); |
| 163 const cc::RenderPassId renderPassId(1, 1); | 172 const cc::RenderPassId renderPassId(1, 1); |
| 164 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); | 173 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); |
| 165 pass->SetAll(renderPassId, bounds, bounds, gfx::Transform(), false); | 174 pass->SetAll(renderPassId, bounds, bounds, gfx::Transform(), false); |
| 166 | 175 |
| 167 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); | 176 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); |
| 168 sqs->SetAll(gfx::Transform(), bounds.size(), bounds, bounds, false, 1.f, | 177 sqs->SetAll(gfx::Transform(), bounds.size(), bounds, bounds, false, 1.f, |
| 169 SkXfermode::kSrcOver_Mode, 0); | 178 SkXfermode::kSrcOver_Mode, 0); |
| 170 | 179 |
| 171 cc::TransferableResource resource; | 180 cc::TransferableResource resource; |
| 172 resource.id = m_nextResourceId; | 181 resource.id = m_nextResourceId; |
| 173 resource.format = cc::ResourceFormat::RGBA_8888; | 182 resource.format = cc::ResourceFormat::RGBA_8888; |
| 174 // TODO(crbug.com/645590): filter should respect the image-rendering CSS | 183 // TODO(crbug.com/645590): filter should respect the image-rendering CSS |
| 175 // property of associated canvas element. | 184 // property of associated canvas element. |
| 176 resource.filter = GL_LINEAR; | 185 resource.filter = GL_LINEAR; |
| 177 resource.size = gfx::Size(m_width, m_height); | 186 resource.size = gfx::Size(m_width, m_height); |
| 178 // TODO(crbug.com/646022): making this overlay-able. | 187 // TODO(crbug.com/646022): making this overlay-able. |
| 179 resource.is_overlay_candidate = false; | 188 resource.is_overlay_candidate = false; |
| 180 | 189 |
| 181 if (!image->isTextureBacked() && | 190 if (!image->isTextureBacked() && |
| 182 !Platform::current()->isGPUCompositingEnabled()) | 191 !Platform::current()->isGPUCompositingEnabled()) |
| 183 setTransferableResourceInMemory(resource, image); | 192 setTransferableResourceInMemory(resource, image); |
| 184 else if (!image->isTextureBacked() && | 193 else if (!image->isTextureBacked() && |
| 185 Platform::current()->isGPUCompositingEnabled()) | 194 Platform::current()->isGPUCompositingEnabled()) |
| 186 setTransferableResourceMemoryToTexture(resource, image); | 195 setTransferableResourceMemoryToTexture(resource, image); |
| 196 else if (image->isTextureBacked() && |
| 197 (!Platform::current()->isGPUCompositingEnabled() || |
| 198 isWebGLSoftwareRendering)) |
| 199 setTransferableResourceInMemory(resource, image); |
| 187 else | 200 else |
| 188 setTransferableResourceInTexture(resource, image); | 201 setTransferableResourceInTexture(resource, image); |
| 189 | 202 |
| 190 m_nextResourceId++; | 203 m_nextResourceId++; |
| 191 frame.delegated_frame_data->resource_list.push_back(std::move(resource)); | 204 frame.delegated_frame_data->resource_list.push_back(std::move(resource)); |
| 192 | 205 |
| 193 cc::TextureDrawQuad* quad = | 206 cc::TextureDrawQuad* quad = |
| 194 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); | 207 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); |
| 195 gfx::Size rectSize(m_width, m_height); | 208 gfx::Size rectSize(m_width, m_height); |
| 196 | 209 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 225 } | 238 } |
| 226 | 239 |
| 227 bool OffscreenCanvasFrameDispatcherImpl::verifyImageSize( | 240 bool OffscreenCanvasFrameDispatcherImpl::verifyImageSize( |
| 228 const sk_sp<SkImage>& image) { | 241 const sk_sp<SkImage>& image) { |
| 229 if (image && image->width() == m_width && image->height() == m_height) | 242 if (image && image->width() == m_width && image->height() == m_height) |
| 230 return true; | 243 return true; |
| 231 return false; | 244 return false; |
| 232 } | 245 } |
| 233 | 246 |
| 234 } // namespace blink | 247 } // namespace blink |
| OLD | NEW |