Commit 8dc4d905 authored by Jonah Chin's avatar Jonah Chin Committed by Chromium LUCI CQ

Revert "Introduce mailbox-based version of VideoTextureBacking"

This reverts commit 0c93bcb5.

Reason for revert: An earlier change is causing a canvas video issue.
This change depends on that change. Reverting both changes until the
bug is resolved. See crbug.com/1164407.

Original change's description:
> Introduce mailbox-based version of VideoTextureBacking
>
> This CL introduces an OOPR compatible version of VideoTextureBacking and
> updates PaintCanvasVideoRenderer::UpdateLastImage() to use this new
> version in the OOPR codepath.
>
> More details about overall PaintImage effort: crbug.com/1023259
> Info about the OOPR-Canvas2D project: crbug.com/1018894
>
> Bug: 1115217
> Change-Id: I4590cf16d6faef0e5575b0b4006ea88de89aa13d
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2419653
> Reviewed-by: Khushal <khushalsagar@chromium.org>
> Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
> Commit-Queue: Jonah Chin <jochin@microsoft.com>
> Cr-Commit-Position: refs/heads/master@{#826449}

TBR=dalecurtis@chromium.org,khushalsagar@chromium.org,jochin@microsoft.com

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 1115217
Change-Id: I3b1d370e7048eee9d8885651ee0e68b342340b9f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2623174Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarJonah Chin <jochin@microsoft.com>
Commit-Queue: Jonah Chin <jochin@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#842354}
parent 670336f2
...@@ -298,6 +298,11 @@ void PaintImage::FlushPendingSkiaOps() { ...@@ -298,6 +298,11 @@ void PaintImage::FlushPendingSkiaOps() {
texture_backing_->FlushPendingSkiaOps(); texture_backing_->FlushPendingSkiaOps();
} }
bool PaintImage::HasExclusiveTextureAccess() const {
DCHECK(IsTextureBacked());
return texture_backing_->unique();
}
int PaintImage::width() const { int PaintImage::width() const {
return paint_worklet_input_ return paint_worklet_input_
? static_cast<int>(paint_worklet_input_->GetSize().width()) ? static_cast<int>(paint_worklet_input_->GetSize().width())
......
...@@ -239,11 +239,10 @@ class CC_PAINT_EXPORT PaintImage { ...@@ -239,11 +239,10 @@ class CC_PAINT_EXPORT PaintImage {
int src_x, int src_x,
int src_y) const; int src_y) const;
// Returned mailbox must not outlive this PaintImage. SkImageInfo GetSkImageInfo() const;
gpu::Mailbox GetMailbox() const;
Id stable_id() const { return id_; } Id stable_id() const { return id_; }
SkImageInfo GetSkImageInfo() const; gpu::Mailbox GetMailbox() const;
AnimationType animation_type() const { return animation_type_; } AnimationType animation_type() const { return animation_type_; }
CompletionState completion_state() const { return completion_state_; } CompletionState completion_state() const { return completion_state_; }
bool is_multipart() const { return is_multipart_; } bool is_multipart() const { return is_multipart_; }
...@@ -266,6 +265,7 @@ class CC_PAINT_EXPORT PaintImage { ...@@ -266,6 +265,7 @@ class CC_PAINT_EXPORT PaintImage {
// Skia internally buffers commands and flushes them as necessary but there // Skia internally buffers commands and flushes them as necessary but there
// are some cases where we need to force a flush. // are some cases where we need to force a flush.
void FlushPendingSkiaOps(); void FlushPendingSkiaOps();
bool HasExclusiveTextureAccess() const;
int width() const; int width() const;
int height() const; int height() const;
SkColorSpace* color_space() const { SkColorSpace* color_space() const {
......
...@@ -1515,14 +1515,9 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op, ...@@ -1515,14 +1515,9 @@ void DrawImageOp::RasterWithFlags(const DrawImageOp* op,
canvas->scale(1.f / op->scale_adjustment.width(), canvas->scale(1.f / op->scale_adjustment.width(),
1.f / op->scale_adjustment.height()); 1.f / op->scale_adjustment.height());
} }
sk_sp<SkImage> sk_image; auto sk_image = op->image.IsTextureBacked()
if (op->image.IsTextureBacked()) { ? op->image.GetAcceleratedSkImage()
sk_image = op->image.GetAcceleratedSkImage(); : op->image.GetSwSkImage();
DCHECK(sk_image || !canvas->recordingContext());
}
if (!sk_image)
sk_image = op->image.GetSwSkImage();
canvas->drawImage(sk_image.get(), op->left, op->top, &paint); canvas->drawImage(sk_image.get(), op->left, op->top, &paint);
return; return;
} }
...@@ -1594,13 +1589,9 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op, ...@@ -1594,13 +1589,9 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op,
if (!params.image_provider) { if (!params.image_provider) {
SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment); SkRect adjusted_src = AdjustSrcRectForScale(op->src, op->scale_adjustment);
flags->DrawToSk(canvas, [op, adjusted_src](SkCanvas* c, const SkPaint& p) { flags->DrawToSk(canvas, [op, adjusted_src](SkCanvas* c, const SkPaint& p) {
sk_sp<SkImage> sk_image; auto sk_image = op->image.IsTextureBacked()
if (op->image.IsTextureBacked()) { ? op->image.GetAcceleratedSkImage()
sk_image = op->image.GetAcceleratedSkImage(); : op->image.GetSwSkImage();
DCHECK(sk_image || !c->recordingContext());
}
if (!sk_image)
sk_image = op->image.GetSwSkImage();
c->drawImageRect(sk_image.get(), adjusted_src, op->dst, &p, c->drawImageRect(sk_image.get(), adjusted_src, op->dst, &p,
op->constraint); op->constraint);
}); });
......
...@@ -1351,10 +1351,8 @@ void WebMediaPlayerImpl::Paint(cc::PaintCanvas* canvas, ...@@ -1351,10 +1351,8 @@ void WebMediaPlayerImpl::Paint(cc::PaintCanvas* canvas,
if (video_frame && video_frame->HasTextures()) { if (video_frame && video_frame->HasTextures()) {
if (!raster_context_provider_) if (!raster_context_provider_)
return; // Unable to get/create a shared main thread context. return; // Unable to get/create a shared main thread context.
if (!raster_context_provider_->GrContext() && if (!raster_context_provider_->GrContext())
!raster_context_provider_->ContextCapabilities().supports_oop_raster) { return; // The context has been lost since and can't setup a GrContext.
return; // The context has been lost.
}
} }
if (out_metadata && video_frame) { if (out_metadata && video_frame) {
// WebGL last-uploaded-frame-metadata API enabled. https://crbug.com/639174 // WebGL last-uploaded-frame-metadata API enabled. https://crbug.com/639174
......
...@@ -800,67 +800,28 @@ class VideoImageGenerator : public cc::PaintImageGenerator { ...@@ -800,67 +800,28 @@ class VideoImageGenerator : public cc::PaintImageGenerator {
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator); DISALLOW_IMPLICIT_CONSTRUCTORS(VideoImageGenerator);
}; };
// TODO(jochin): Add support for all OOP-R specific APIs (eg. GetMailbox() and
// GetSkImageViaReadback())
class VideoTextureBacking : public cc::TextureBacking { class VideoTextureBacking : public cc::TextureBacking {
public: public:
explicit VideoTextureBacking( explicit VideoTextureBacking(
sk_sp<SkImage> sk_image, sk_sp<SkImage> sk_image,
const gpu::Mailbox& mailbox,
bool wraps_video_frame_texture,
scoped_refptr<viz::RasterContextProvider> raster_context_provider) scoped_refptr<viz::RasterContextProvider> raster_context_provider)
: sk_image_(std::move(sk_image)), : sk_image_(std::move(sk_image)) {
sk_image_info_(sk_image_->imageInfo()),
mailbox_(mailbox),
wraps_video_frame_texture_(wraps_video_frame_texture) {
raster_context_provider_ = std::move(raster_context_provider); raster_context_provider_ = std::move(raster_context_provider);
} }
explicit VideoTextureBacking( const SkImageInfo& GetSkImageInfo() override {
const gpu::Mailbox& mailbox, return sk_image_->imageInfo();
const SkImageInfo& info,
bool wraps_video_frame_texture,
scoped_refptr<viz::RasterContextProvider> raster_context_provider)
: sk_image_info_(info),
mailbox_(mailbox),
wraps_video_frame_texture_(wraps_video_frame_texture) {
raster_context_provider_ = std::move(raster_context_provider);
} }
~VideoTextureBacking() override {
auto* ri = raster_context_provider_->RasterInterface();
if (!wraps_video_frame_texture_) {
gpu::SyncToken sync_token;
ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
auto* sii = raster_context_provider_->SharedImageInterface();
sii->DestroySharedImage(sync_token, mailbox_);
}
}
const SkImageInfo& GetSkImageInfo() override { return sk_image_info_; }
gpu::Mailbox GetMailbox() const override { return mailbox_; } gpu::Mailbox GetMailbox() const override { return mailbox_; }
sk_sp<SkImage> GetAcceleratedSkImage() override { return sk_image_; } sk_sp<SkImage> GetAcceleratedSkImage() override { return sk_image_; }
bool wraps_video_frame_texture() const { return wraps_video_frame_texture_; }
const scoped_refptr<viz::RasterContextProvider>& raster_context_provider()
const {
return raster_context_provider_;
}
sk_sp<SkImage> GetSkImageViaReadback() override { sk_sp<SkImage> GetSkImageViaReadback() override {
if (sk_image_) if (sk_image_) {
return sk_image_->makeNonTextureImage(); return sk_image_->makeNonTextureImage();
}
sk_sp<SkData> image_pixels = return nullptr;
SkData::MakeUninitialized(sk_image_info_.computeMinByteSize());
uint8_t* writable_pixels =
static_cast<uint8_t*>(image_pixels->writable_data());
gpu::raster::RasterInterface* ri =
raster_context_provider_->RasterInterface();
ri->ReadbackImagePixels(mailbox_, sk_image_info_,
sk_image_info_.minRowBytes(), 0, 0,
writable_pixels);
return SkImage::MakeRasterData(sk_image_info_, std::move(image_pixels),
sk_image_info_.minRowBytes());
} }
bool readPixels(const SkImageInfo& dst_info, bool readPixels(const SkImageInfo& dst_info,
void* dst_pixels, void* dst_pixels,
size_t dst_row_bytes, size_t dst_row_bytes,
...@@ -870,13 +831,8 @@ class VideoTextureBacking : public cc::TextureBacking { ...@@ -870,13 +831,8 @@ class VideoTextureBacking : public cc::TextureBacking {
return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x, return sk_image_->readPixels(dst_info, dst_pixels, dst_row_bytes, src_x,
src_y); src_y);
} }
gpu::raster::RasterInterface* ri = return false;
raster_context_provider_->RasterInterface();
ri->ReadbackImagePixels(mailbox_, dst_info, dst_info.minRowBytes(), src_x,
src_y, dst_pixels);
return true;
} }
void FlushPendingSkiaOps() override { void FlushPendingSkiaOps() override {
if (!raster_context_provider_ || !sk_image_) if (!raster_context_provider_ || !sk_image_)
return; return;
...@@ -884,19 +840,9 @@ class VideoTextureBacking : public cc::TextureBacking { ...@@ -884,19 +840,9 @@ class VideoTextureBacking : public cc::TextureBacking {
} }
private: private:
sk_sp<SkImage> sk_image_; const sk_sp<SkImage> sk_image_;
SkImageInfo sk_image_info_;
scoped_refptr<viz::RasterContextProvider> raster_context_provider_;
// This can be either the source VideoFrame's texture (if
// |wraps_video_frame_texture_| is true) or a newly allocated shared image
// (if |wraps_video_frame_texture_| is false) if a copy or conversion was
// necessary.
const gpu::Mailbox mailbox_; const gpu::Mailbox mailbox_;
scoped_refptr<viz::RasterContextProvider> raster_context_provider_;
// Whether |mailbox_| directly points to a texture of the VideoFrame
// (if true), or to an allocated shared image (if false).
const bool wraps_video_frame_texture_;
}; };
PaintCanvasVideoRenderer::PaintCanvasVideoRenderer() PaintCanvasVideoRenderer::PaintCanvasVideoRenderer()
...@@ -952,11 +898,11 @@ void PaintCanvasVideoRenderer::Paint( ...@@ -952,11 +898,11 @@ void PaintCanvasVideoRenderer::Paint(
DCHECK(image); DCHECK(image);
base::Optional<ScopedSharedImageAccess> source_access; base::Optional<ScopedSharedImageAccess> source_access;
if (video_frame->HasTextures() && cache_->source_texture) { if (video_frame->HasTextures()) {
DCHECK(cache_->texture_backing); DCHECK(!cache_->source_mailbox.IsZero());
DCHECK(cache_->source_texture);
source_access.emplace(raster_context_provider->RasterInterface(), source_access.emplace(raster_context_provider->RasterInterface(),
cache_->source_texture, cache_->source_texture, cache_->source_mailbox);
cache_->texture_backing->GetMailbox());
} }
cc::PaintFlags video_flags; cc::PaintFlags video_flags;
...@@ -1048,9 +994,9 @@ void PaintCanvasVideoRenderer::Paint( ...@@ -1048,9 +994,9 @@ void PaintCanvasVideoRenderer::Paint(
raster_context_provider->ContextSupport()); raster_context_provider->ContextSupport());
} }
// Because we are not retaining a reference to the VideoFrame, it would be // Because we are not retaining a reference to the VideoFrame, it would be
// invalid for the texture_backing to directly wrap its texture(s), as they // invalid for the cache to directly wrap its texture(s), as they will be
// will be recycled. // recycled.
DCHECK(!CacheBackingWrapsTexture()); DCHECK(!cache_ || !cache_->wraps_video_frame_texture);
} }
void PaintCanvasVideoRenderer::Copy( void PaintCanvasVideoRenderer::Copy(
...@@ -1380,8 +1326,7 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( ...@@ -1380,8 +1326,7 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
if (!raster_context_provider) if (!raster_context_provider)
return false; return false;
GrDirectContext* gr_context = raster_context_provider->GrContext(); GrDirectContext* gr_context = raster_context_provider->GrContext();
if (!gr_context && if (!gr_context)
!raster_context_provider->ContextCapabilities().supports_oop_raster)
return false; return false;
// TODO(crbug.com/1108154): Expand this uploading path to macOS, linux // TODO(crbug.com/1108154): Expand this uploading path to macOS, linux
// chromeOS after collecting perf data and resolve failure cases. // chromeOS after collecting perf data and resolve failure cases.
...@@ -1407,7 +1352,7 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( ...@@ -1407,7 +1352,7 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
} }
DCHECK(cache_); DCHECK(cache_);
DCHECK(cache_->texture_backing); DCHECK(!cache_->source_mailbox.IsZero());
gpu::raster::RasterInterface* canvas_ri = gpu::raster::RasterInterface* canvas_ri =
raster_context_provider->RasterInterface(); raster_context_provider->RasterInterface();
...@@ -1417,10 +1362,10 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( ...@@ -1417,10 +1362,10 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
canvas_ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); canvas_ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
uint32_t intermediate_texture = SynchronizeAndImportMailbox( uint32_t intermediate_texture = SynchronizeAndImportMailbox(
destination_gl, sync_token, cache_->texture_backing->GetMailbox()); destination_gl, sync_token, cache_->source_mailbox);
{ {
ScopedSharedImageAccess access(destination_gl, intermediate_texture, ScopedSharedImageAccess access(destination_gl, intermediate_texture,
cache_->texture_backing->GetMailbox()); cache_->source_mailbox);
VideoFrameCopyTextureOrSubTexture( VideoFrameCopyTextureOrSubTexture(
destination_gl, cache_->coded_size, cache_->visible_rect, destination_gl, cache_->coded_size, cache_->visible_rect,
intermediate_texture, target, texture, internal_format, format, type, intermediate_texture, target, texture, internal_format, format, type,
...@@ -1438,7 +1383,7 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( ...@@ -1438,7 +1383,7 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
// Because we are not retaining a reference to the VideoFrame, it would be // Because we are not retaining a reference to the VideoFrame, it would be
// invalid to keep the cache around if it directly wraps the VideoFrame // invalid to keep the cache around if it directly wraps the VideoFrame
// texture(s), as they will be recycled. // texture(s), as they will be recycled.
if (cache_->texture_backing->wraps_video_frame_texture()) if (cache_->wraps_video_frame_texture)
cache_.reset(); cache_.reset();
// Synchronize |video_frame| with the read operations in UpdateLastImage(), // Synchronize |video_frame| with the read operations in UpdateLastImage(),
...@@ -1453,7 +1398,8 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( ...@@ -1453,7 +1398,8 @@ bool PaintCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
WaitAndReplaceSyncTokenClient client(destination_gl); WaitAndReplaceSyncTokenClient client(destination_gl);
video_frame->UpdateReleaseSyncToken(&client); video_frame->UpdateReleaseSyncToken(&client);
} }
DCHECK(!CacheBackingWrapsTexture()); DCHECK(!cache_ || !cache_->wraps_video_frame_texture);
return true; return true;
} }
...@@ -1486,7 +1432,6 @@ bool PaintCanvasVideoRenderer::UploadVideoFrameToGLTexture( ...@@ -1486,7 +1432,6 @@ bool PaintCanvasVideoRenderer::UploadVideoFrameToGLTexture(
return false; return false;
} }
// TODO(nazabris): Support OOP-R code path here that does not have GrContext.
if (!raster_context_provider || !raster_context_provider->GrContext()) if (!raster_context_provider || !raster_context_provider->GrContext())
return false; return false;
...@@ -1546,7 +1491,6 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL( ...@@ -1546,7 +1491,6 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL(
return false; return false;
} }
// TODO(nazabris): Support OOP-R code path here that does not have GrContext.
if (!raster_context_provider || !raster_context_provider->GrContext()) if (!raster_context_provider || !raster_context_provider->GrContext())
return false; return false;
...@@ -1584,7 +1528,7 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL( ...@@ -1584,7 +1528,7 @@ bool PaintCanvasVideoRenderer::PrepareVideoFrameForWebGL(
WaitAndReplaceSyncTokenClient client(source_ri); WaitAndReplaceSyncTokenClient client(source_ri);
video_frame->UpdateReleaseSyncToken(&client); video_frame->UpdateReleaseSyncToken(&client);
DCHECK(!CacheBackingWrapsTexture()); DCHECK(!cache_ || !cache_->wraps_video_frame_texture);
return true; return true;
} }
...@@ -1758,17 +1702,33 @@ void PaintCanvasVideoRenderer::ResetCache() { ...@@ -1758,17 +1702,33 @@ void PaintCanvasVideoRenderer::ResetCache() {
PaintCanvasVideoRenderer::Cache::Cache(int frame_id) : frame_id(frame_id) {} PaintCanvasVideoRenderer::Cache::Cache(int frame_id) : frame_id(frame_id) {}
PaintCanvasVideoRenderer::Cache::~Cache() = default; PaintCanvasVideoRenderer::Cache::~Cache() {
if (!raster_context_provider)
return;
bool PaintCanvasVideoRenderer::Cache::Recycle() { DCHECK(!source_mailbox.IsZero());
DCHECK(!texture_backing->wraps_video_frame_texture()); DCHECK(source_texture);
auto* ri = raster_context_provider->RasterInterface();
if (!wraps_video_frame_texture) {
gpu::SyncToken sync_token;
ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
auto* sii = raster_context_provider->SharedImageInterface();
sii->DestroySharedImage(sync_token, source_mailbox);
}
}
paint_image = cc::PaintImage(); bool PaintCanvasVideoRenderer::Cache::Recycle() {
if (!texture_backing->unique()) DCHECK(!wraps_video_frame_texture);
if (!paint_image.HasExclusiveTextureAccess())
return false; return false;
// Flush any pending GPU work using this texture. // Flush any pending GPU work using this texture.
texture_backing->FlushPendingSkiaOps(); paint_image.FlushPendingSkiaOps();
paint_image = cc::PaintImage();
// We need a new texture ID because skia will destroy the previous one with
// the SkImage.
source_texture = 0;
return true; return true;
} }
...@@ -1776,9 +1736,9 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1776,9 +1736,9 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
scoped_refptr<VideoFrame> video_frame, scoped_refptr<VideoFrame> video_frame,
viz::RasterContextProvider* raster_context_provider, viz::RasterContextProvider* raster_context_provider,
bool allow_wrap_texture) { bool allow_wrap_texture) {
DCHECK(!CacheBackingWrapsTexture()); DCHECK(!cache_ || !cache_->wraps_video_frame_texture);
if (!cache_ || video_frame->unique_id() != cache_->frame_id || if (!cache_ || video_frame->unique_id() != cache_->frame_id ||
!cache_->paint_image) { cache_->source_mailbox.IsZero()) {
auto paint_image_builder = auto paint_image_builder =
cc::PaintImageBuilder::WithDefault() cc::PaintImageBuilder::WithDefault()
.set_id(renderer_stable_id_) .set_id(renderer_stable_id_)
...@@ -1792,30 +1752,24 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1792,30 +1752,24 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
// could cause problems since the pool of VideoFrames has a fixed size. // could cause problems since the pool of VideoFrames has a fixed size.
if (video_frame->HasTextures()) { if (video_frame->HasTextures()) {
DCHECK(raster_context_provider); DCHECK(raster_context_provider);
bool supports_oop_raster = DCHECK(raster_context_provider->GrContext());
raster_context_provider->ContextCapabilities().supports_oop_raster;
DCHECK(supports_oop_raster || raster_context_provider->GrContext());
auto* ri = raster_context_provider->RasterInterface(); auto* ri = raster_context_provider->RasterInterface();
DCHECK(ri); DCHECK(ri);
bool wraps_video_frame_texture = false;
gpu::Mailbox mailbox;
if (allow_wrap_texture && video_frame->NumTextures() == 1) { if (allow_wrap_texture && video_frame->NumTextures() == 1) {
cache_.emplace(video_frame->unique_id()); cache_.emplace(video_frame->unique_id());
const gpu::MailboxHolder& holder = const gpu::MailboxHolder& holder =
GetVideoFrameMailboxHolder(video_frame.get()); GetVideoFrameMailboxHolder(video_frame.get());
mailbox = holder.mailbox; cache_->source_mailbox = holder.mailbox;
ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData()); ri->WaitSyncTokenCHROMIUM(holder.sync_token.GetConstData());
wraps_video_frame_texture = true; cache_->wraps_video_frame_texture = true;
} else { } else {
if (cache_ && cache_->texture_backing && if (cache_ &&
cache_->texture_backing->raster_context_provider() == cache_->raster_context_provider == raster_context_provider &&
raster_context_provider &&
cache_->coded_size == video_frame->coded_size() && cache_->coded_size == video_frame->coded_size() &&
cache_->Recycle()) { cache_->Recycle()) {
// We can reuse the shared image from the previous cache. // We can reuse the shared image from the previous cache.
cache_->frame_id = video_frame->unique_id(); cache_->frame_id = video_frame->unique_id();
mailbox = cache_->texture_backing->GetMailbox();
} else { } else {
cache_.emplace(video_frame->unique_id()); cache_.emplace(video_frame->unique_id());
auto* sii = raster_context_provider->SharedImageInterface(); auto* sii = raster_context_provider->SharedImageInterface();
...@@ -1823,10 +1777,11 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1823,10 +1777,11 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
// cached shared image is created without it. // cached shared image is created without it.
uint32_t flags = uint32_t flags =
gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_RASTER; gpu::SHARED_IMAGE_USAGE_GLES2 | gpu::SHARED_IMAGE_USAGE_RASTER;
if (supports_oop_raster) { if (raster_context_provider->ContextCapabilities()
.supports_oop_raster) {
flags |= gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION; flags |= gpu::SHARED_IMAGE_USAGE_OOP_RASTERIZATION;
} }
mailbox = sii->CreateSharedImage( cache_->source_mailbox = sii->CreateSharedImage(
viz::ResourceFormat::RGBA_8888, video_frame->coded_size(), viz::ResourceFormat::RGBA_8888, video_frame->coded_size(),
gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType,
flags, gpu::kNullSurfaceHandle); flags, gpu::kNullSurfaceHandle);
...@@ -1836,55 +1791,48 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1836,55 +1791,48 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
if (video_frame->NumTextures() == 1) { if (video_frame->NumTextures() == 1) {
auto frame_mailbox = auto frame_mailbox =
SynchronizeVideoFrameSingleMailbox(ri, video_frame.get()); SynchronizeVideoFrameSingleMailbox(ri, video_frame.get());
ri->CopySubTexture(frame_mailbox, mailbox, GL_TEXTURE_2D, 0, 0, 0, 0, ri->CopySubTexture(
video_frame->coded_size().width(), frame_mailbox, cache_->source_mailbox, GL_TEXTURE_2D, 0, 0, 0, 0,
video_frame->coded_size().height(), GL_FALSE, video_frame->coded_size().width(),
GL_FALSE); video_frame->coded_size().height(), GL_FALSE, GL_FALSE);
} else { } else {
gpu::MailboxHolder dest_holder{mailbox, gpu::SyncToken(), gpu::MailboxHolder dest_holder{cache_->source_mailbox,
GL_TEXTURE_2D}; gpu::SyncToken(), GL_TEXTURE_2D};
VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching( VideoFrameYUVConverter::ConvertYUVVideoFrameNoCaching(
video_frame.get(), raster_context_provider, dest_holder); video_frame.get(), raster_context_provider, dest_holder);
} }
if (!supports_oop_raster) raster_context_provider->GrContext()->flushAndSubmit();
raster_context_provider->GrContext()->flushAndSubmit();
} }
// TODO(jochin): Don't always generate SkImage here.
DCHECK(cache_->source_texture == 0);
cache_->source_texture =
ri->CreateAndConsumeForGpuRaster(cache_->source_mailbox);
// TODO(nazabris): Handle scoped access correctly. This follows the
// current pattern but is most likely bugged. Access should last for the
// lifetime of the SkImage.
ScopedSharedImageAccess(ri, cache_->source_texture,
cache_->source_mailbox);
auto source_image =
WrapGLTexture(cache_->wraps_video_frame_texture
? video_frame->mailbox_holder(0).texture_target
: GL_TEXTURE_2D,
cache_->source_texture, video_frame->coded_size(),
video_frame->ColorSpace(), raster_context_provider);
if (!source_image) {
// Couldn't create the SkImage.
cache_.reset();
return false;
}
cache_->raster_context_provider = raster_context_provider;
cache_->coded_size = video_frame->coded_size(); cache_->coded_size = video_frame->coded_size();
cache_->visible_rect = video_frame->visible_rect(); cache_->visible_rect = video_frame->visible_rect();
if (!cache_->texture_backing) {
if (supports_oop_raster) {
SkImageInfo sk_image_info = SkImageInfo::Make(
gfx::SizeToSkISize(cache_->coded_size), kRGBA_8888_SkColorType,
kPremul_SkAlphaType, video_frame->ColorSpace().ToSkColorSpace());
cache_->texture_backing = sk_make_sp<VideoTextureBacking>(
mailbox, sk_image_info, wraps_video_frame_texture,
raster_context_provider);
} else {
cache_->source_texture = ri->CreateAndConsumeForGpuRaster(mailbox);
// TODO(nazabris): Handle scoped access correctly. This follows the
// current pattern but is most likely bugged. Access should last for
// the lifetime of the SkImage.
ScopedSharedImageAccess(ri, cache_->source_texture, mailbox);
auto source_image =
WrapGLTexture(wraps_video_frame_texture
? video_frame->mailbox_holder(0).texture_target
: GL_TEXTURE_2D,
cache_->source_texture, video_frame->coded_size(),
video_frame->ColorSpace(), raster_context_provider);
if (!source_image) {
// Couldn't create the SkImage.
cache_.reset();
return false;
}
cache_->texture_backing = sk_make_sp<VideoTextureBacking>(
std::move(source_image), mailbox, wraps_video_frame_texture,
raster_context_provider);
}
}
paint_image_builder.set_texture_backing( paint_image_builder.set_texture_backing(
cache_->texture_backing, cc::PaintImage::GetNextContentId()); sk_sp<VideoTextureBacking>(new VideoTextureBacking(
std::move(source_image), raster_context_provider)),
cc::PaintImage::GetNextContentId());
} else { } else {
cache_.emplace(video_frame->unique_id()); cache_.emplace(video_frame->unique_id());
paint_image_builder.set_paint_image_generator( paint_image_builder.set_paint_image_generator(
...@@ -1892,7 +1840,7 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1892,7 +1840,7 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
} }
cache_->paint_image = paint_image_builder.TakePaintImage(); cache_->paint_image = paint_image_builder.TakePaintImage();
if (!cache_->paint_image) { if (!cache_->paint_image) {
// Couldn't create the PaintImage. // Couldn't create the SkImage.
cache_.reset(); cache_.reset();
return false; return false;
} }
...@@ -1955,9 +1903,4 @@ gfx::Size PaintCanvasVideoRenderer::LastImageDimensionsForTesting() { ...@@ -1955,9 +1903,4 @@ gfx::Size PaintCanvasVideoRenderer::LastImageDimensionsForTesting() {
return gfx::Size(cache_->paint_image.width(), cache_->paint_image.height()); return gfx::Size(cache_->paint_image.width(), cache_->paint_image.height());
} }
bool PaintCanvasVideoRenderer::CacheBackingWrapsTexture() const {
return cache_ && cache_->texture_backing &&
cache_->texture_backing->wraps_video_frame_texture();
}
} // namespace media } // namespace media
...@@ -41,7 +41,6 @@ class RasterContextProvider; ...@@ -41,7 +41,6 @@ class RasterContextProvider;
} }
namespace media { namespace media {
class VideoTextureBacking;
// Handles rendering of VideoFrames to PaintCanvases. // Handles rendering of VideoFrames to PaintCanvases.
class MEDIA_EXPORT PaintCanvasVideoRenderer { class MEDIA_EXPORT PaintCanvasVideoRenderer {
...@@ -212,15 +211,22 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer { ...@@ -212,15 +211,22 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer {
// to the visible size of the VideoFrame. Its contents are generated lazily. // to the visible size of the VideoFrame. Its contents are generated lazily.
cc::PaintImage paint_image; cc::PaintImage paint_image;
// The backing for the source texture. This is also responsible for managing // The context provider used to generate |source_mailbox| and
// the lifetime of the texture. // |source_texture|. This is only set if the VideoFrame was texture-backed.
sk_sp<VideoTextureBacking> texture_backing; scoped_refptr<viz::RasterContextProvider> raster_context_provider;
// The mailbox for the source texture. This can be either the source
// VideoFrame's texture (if |wraps_video_frame_texture| is true) or a newly
// allocated shared image (if |wraps_video_frame_texture| is false) if a
// copy or conversion was necessary.
// This is only set if the VideoFrame was texture-backed.
gpu::Mailbox source_mailbox;
// The GL texture ID used in non-OOP code path. // The texture ID created when importing |source_mailbox|.
// This is only set if the VideoFrame was texture-backed. // This is only set if the VideoFrame was texture-backed.
uint32_t source_texture = 0; uint32_t source_texture = 0;
// The allocated size of VideoFrame texture. // The allocated size of |source_mailbox|.
// This is only set if the VideoFrame was texture-backed. // This is only set if the VideoFrame was texture-backed.
gfx::Size coded_size; gfx::Size coded_size;
...@@ -229,6 +235,10 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer { ...@@ -229,6 +235,10 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer {
// This is only set if the VideoFrame was texture-backed. // This is only set if the VideoFrame was texture-backed.
gfx::Rect visible_rect; gfx::Rect visible_rect;
// Whether |source_mailbox| directly points to a texture of the VideoFrame
// (if true), or to an allocated shared image (if false).
bool wraps_video_frame_texture = false;
// Used to allow recycling of the previous shared image. This requires that // Used to allow recycling of the previous shared image. This requires that
// no external users have access to this resource via SkImage. Returns true // no external users have access to this resource via SkImage. Returns true
// if the existing resource can be recycled. // if the existing resource can be recycled.
...@@ -256,8 +266,6 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer { ...@@ -256,8 +266,6 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer {
unsigned int type, unsigned int type,
bool flip_y); bool flip_y);
bool CacheBackingWrapsTexture() const;
base::Optional<Cache> cache_; base::Optional<Cache> cache_;
// If |cache_| is not used for a while, it's deleted to save memory. // If |cache_| is not used for a while, it's deleted to save memory.
......
...@@ -377,8 +377,8 @@ gpu::ContextSupport* ContextProviderCommandBuffer::ContextSupport() { ...@@ -377,8 +377,8 @@ gpu::ContextSupport* ContextProviderCommandBuffer::ContextSupport() {
class GrDirectContext* ContextProviderCommandBuffer::GrContext() { class GrDirectContext* ContextProviderCommandBuffer::GrContext() {
DCHECK(bind_tried_); DCHECK(bind_tried_);
DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess); DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess);
if (!support_grcontext_ || !ContextSupport()->HasGrContextSupport()) DCHECK(support_grcontext_);
return nullptr; DCHECK(ContextSupport()->HasGrContextSupport());
CheckValidThreadOrLockAcquired(); CheckValidThreadOrLockAcquired();
if (gr_context_) if (gr_context_)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment