Commit 4107e01f authored by Jonah Chin's avatar Jonah Chin Committed by Commit Bot

Change texture subset logic in PaintCanvasVideoRenderer

This CL is to simplify how PaintCanvasVideoRenderer::Cache manages
video frames whose |visible_rect| is smaller than their |coded_size|.
By always using SkImage::MakeFromAdoptedTexture, texture lifetime
management is now always handled internally by skia. This will make the
transition to OOPR here much simpler.

More details about overall PaintImage effort: crbug.com/1023259
Info about the OOPR-Canvas2D project: crbug.com/1018894

Bug: 1115217
Change-Id: I2177b2deeea893fa5331afbe8796761253db2759
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2451213
Commit-Queue: Jonah Chin <jochin@microsoft.com>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818045}
parent 883da05a
...@@ -254,10 +254,10 @@ sk_sp<SkImage> WrapGLTexture( ...@@ -254,10 +254,10 @@ sk_sp<SkImage> WrapGLTexture(
texture_info.fFormat = GL_RGBA8_OES; texture_info.fFormat = GL_RGBA8_OES;
GrBackendTexture backend_texture(size.width(), size.height(), GrBackendTexture backend_texture(size.width(), size.height(),
GrMipMapped::kNo, texture_info); GrMipMapped::kNo, texture_info);
return SkImage::MakeFromTexture( return SkImage::MakeFromAdoptedTexture(
raster_context_provider->GrContext(), backend_texture, raster_context_provider->GrContext(), backend_texture,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
color_space.ToSkColorSpace(), nullptr, nullptr); color_space.ToSkColorSpace());
} }
void VideoFrameCopyTextureOrSubTexture(gpu::gles2::GLES2Interface* gl, void VideoFrameCopyTextureOrSubTexture(gpu::gles2::GLES2Interface* gl,
...@@ -854,7 +854,7 @@ void PaintCanvasVideoRenderer::Paint( ...@@ -854,7 +854,7 @@ void PaintCanvasVideoRenderer::Paint(
const bool need_rotation = video_transformation.rotation != VIDEO_ROTATION_0; const bool need_rotation = video_transformation.rotation != VIDEO_ROTATION_0;
const bool need_scaling = const bool need_scaling =
dest_rect.size() != gfx::SizeF(image.width(), image.height()); dest_rect.size() != gfx::SizeF(video_frame->visible_rect().size());
const bool need_translation = !dest_rect.origin().IsOrigin(); const bool need_translation = !dest_rect.origin().IsOrigin();
// TODO(tmathmeyer): apply horizontal / vertical mirroring if needed. // TODO(tmathmeyer): apply horizontal / vertical mirroring if needed.
bool need_transform = need_rotation || need_scaling || need_translation; bool need_transform = need_rotation || need_scaling || need_translation;
...@@ -885,10 +885,13 @@ void PaintCanvasVideoRenderer::Paint( ...@@ -885,10 +885,13 @@ void PaintCanvasVideoRenderer::Paint(
rotated_dest_size = rotated_dest_size =
gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width()); gfx::SizeF(rotated_dest_size.height(), rotated_dest_size.width());
} }
canvas->scale(SkFloatToScalar(rotated_dest_size.width() / image.width()), canvas->scale(SkFloatToScalar(rotated_dest_size.width() /
SkFloatToScalar(rotated_dest_size.height() / image.height())); video_frame->visible_rect().width()),
canvas->translate(-SkFloatToScalar(image.width() * 0.5f), SkFloatToScalar(rotated_dest_size.height() /
-SkFloatToScalar(image.height() * 0.5f)); video_frame->visible_rect().height()));
canvas->translate(
-SkFloatToScalar(video_frame->visible_rect().width() * 0.5f),
-SkFloatToScalar(video_frame->visible_rect().height() * 0.5f));
} }
SkImageInfo info; SkImageInfo info;
...@@ -907,7 +910,15 @@ void PaintCanvasVideoRenderer::Paint( ...@@ -907,7 +910,15 @@ void PaintCanvasVideoRenderer::Paint(
const size_t offset = info.computeOffset(origin.x(), origin.y(), row_bytes); const size_t offset = info.computeOffset(origin.x(), origin.y(), row_bytes);
void* const pixels_offset = reinterpret_cast<char*>(pixels) + offset; void* const pixels_offset = reinterpret_cast<char*>(pixels) + offset;
ConvertVideoFrameToRGBPixels(video_frame.get(), pixels_offset, row_bytes); ConvertVideoFrameToRGBPixels(video_frame.get(), pixels_offset, row_bytes);
} else if (video_frame->HasTextures()) {
DCHECK_EQ(video_frame->coded_size(),
gfx::Size(image.width(), image.height()));
canvas->drawImageRect(image, gfx::RectToSkRect(video_frame->visible_rect()),
dest, &video_flags,
SkCanvas::kStrict_SrcRectConstraint);
} else { } else {
DCHECK_EQ(video_frame->visible_rect().size(),
gfx::Size(image.width(), image.height()));
canvas->drawImage(image, 0, 0, &video_flags); canvas->drawImage(image, 0, 0, &video_flags);
} }
...@@ -1636,8 +1647,6 @@ PaintCanvasVideoRenderer::Cache::~Cache() { ...@@ -1636,8 +1647,6 @@ PaintCanvasVideoRenderer::Cache::~Cache() {
DCHECK(!source_mailbox.IsZero()); DCHECK(!source_mailbox.IsZero());
DCHECK(source_texture); DCHECK(source_texture);
auto* ri = raster_context_provider->RasterInterface(); auto* ri = raster_context_provider->RasterInterface();
if (!texture_ownership_in_skia)
ri->DeleteGpuRasterTexture(source_texture);
if (!wraps_video_frame_texture) { if (!wraps_video_frame_texture) {
gpu::SyncToken sync_token; gpu::SyncToken sync_token;
ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData()); ri->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
...@@ -1647,9 +1656,7 @@ PaintCanvasVideoRenderer::Cache::~Cache() { ...@@ -1647,9 +1656,7 @@ PaintCanvasVideoRenderer::Cache::~Cache() {
} }
bool PaintCanvasVideoRenderer::Cache::Recycle() { bool PaintCanvasVideoRenderer::Cache::Recycle() {
if (!texture_ownership_in_skia) DCHECK(!wraps_video_frame_texture);
return true;
if (!paint_image.HasExclusiveTextureAccess()) if (!paint_image.HasExclusiveTextureAccess())
return false; return false;
...@@ -1659,7 +1666,6 @@ bool PaintCanvasVideoRenderer::Cache::Recycle() { ...@@ -1659,7 +1666,6 @@ bool PaintCanvasVideoRenderer::Cache::Recycle() {
paint_image = cc::PaintImage(); paint_image = cc::PaintImage();
// We need a new texture ID because skia will destroy the previous one with // We need a new texture ID because skia will destroy the previous one with
// the SkImage. // the SkImage.
texture_ownership_in_skia = false;
source_texture = 0; source_texture = 0;
return true; return true;
} }
...@@ -1705,7 +1711,6 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1705,7 +1711,6 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
} 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();
// TODO(nazabris): Sort out what to do when GLES2 is needed but the // TODO(nazabris): Sort out what to do when GLES2 is needed but the
// cached shared image is created without it. // cached shared image is created without it.
uint32_t flags = uint32_t flags =
...@@ -1721,8 +1726,6 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1721,8 +1726,6 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
ri->WaitSyncTokenCHROMIUM( ri->WaitSyncTokenCHROMIUM(
sii->GenUnverifiedSyncToken().GetConstData()); sii->GenUnverifiedSyncToken().GetConstData());
} }
DCHECK(!cache_->texture_ownership_in_skia);
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());
...@@ -1763,35 +1766,10 @@ bool PaintCanvasVideoRenderer::UpdateLastImage( ...@@ -1763,35 +1766,10 @@ bool PaintCanvasVideoRenderer::UpdateLastImage(
cache_->raster_context_provider = raster_context_provider; 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();
GrDirectContext* direct =
GrAsDirectContext(raster_context_provider->GrContext());
sk_sp<SkImage> source_subset = source_image->makeSubset(
gfx::RectToSkIRect(cache_->visible_rect), direct);
if (source_subset) {
// We use the flushPendingGrContextIO = true so we can flush any pending
// GPU work on the GrContext to ensure that skia exectues the work for
// generating the subset and it can be safely destroyed.
GrBackendTexture image_backend =
source_image->getBackendTexture(/*flushPendingGrContextIO*/ true);
GrBackendTexture subset_backend =
source_subset->getBackendTexture(/*flushPendingGrContextIO*/ true);
#if DCHECK_IS_ON()
GrGLTextureInfo backend_info;
if (image_backend.getGLTextureInfo(&backend_info))
DCHECK_EQ(backend_info.fID, cache_->source_texture);
#endif
if (subset_backend.isValid() &&
subset_backend.isSameTexture(image_backend)) {
cache_->texture_ownership_in_skia = true;
source_subset = SkImage::MakeFromAdoptedTexture(
cache_->raster_context_provider->GrContext(), image_backend,
kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
kPremul_SkAlphaType, source_image->imageInfo().refColorSpace());
}
}
paint_image_builder.set_texture_backing( paint_image_builder.set_texture_backing(
sk_sp<VideoTextureBacking>(new VideoTextureBacking( sk_sp<VideoTextureBacking>(new VideoTextureBacking(
std::move(source_subset), raster_context_provider)), std::move(source_image), raster_context_provider)),
cc::PaintImage::GetNextContentId()); cc::PaintImage::GetNextContentId());
} else { } else {
cache_.emplace(video_frame->unique_id()); cache_.emplace(video_frame->unique_id());
......
...@@ -239,9 +239,6 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer { ...@@ -239,9 +239,6 @@ class MEDIA_EXPORT PaintCanvasVideoRenderer {
// (if true), or to an allocated shared image (if false). // (if true), or to an allocated shared image (if false).
bool wraps_video_frame_texture = false; bool wraps_video_frame_texture = false;
// Whether the texture pointed by |paint_image| is owned by skia or not.
bool texture_ownership_in_skia = 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.
......
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