Commit e300850a authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Fix SkiaRenderer + DDL related crash.

Skia has a problem to with GrResourceCache. This CL workaround the issue
by not keep a SkPaint object during frames.

Bug: 905337
Change-Id: I0f44eb7502d41cd54015fe651a373d8bae65fda8
Reviewed-on: https://chromium-review.googlesource.com/c/1342501
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarweiliangc <weiliangc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609426}
parent 59b5f94b
...@@ -541,7 +541,7 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad, ...@@ -541,7 +541,7 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad,
PrepareCanvasForDrawQuads(quad->shared_quad_state, draw_region, scissor_rect, PrepareCanvasForDrawQuads(quad->shared_quad_state, draw_region, scissor_rect,
&auto_canvas_restore); &auto_canvas_restore);
current_paint_.reset(); SkPaint paint;
if (settings_->force_antialiasing || if (settings_->force_antialiasing ||
!IsScaleAndIntegerTranslate(current_canvas_->getTotalMatrix())) { !IsScaleAndIntegerTranslate(current_canvas_->getTotalMatrix())) {
// TODO(danakj): Until we can enable AA only on exterior edges of the // TODO(danakj): Until we can enable AA only on exterior edges of the
...@@ -551,30 +551,29 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad, ...@@ -551,30 +551,29 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad,
quad->IsRightEdge(); quad->IsRightEdge();
if (settings_->allow_antialiasing && if (settings_->allow_antialiasing &&
(settings_->force_antialiasing || all_four_edges_are_exterior)) (settings_->force_antialiasing || all_four_edges_are_exterior))
current_paint_.setAntiAlias(true); paint.setAntiAlias(true);
current_paint_.setFilterQuality(kLow_SkFilterQuality); paint.setFilterQuality(kLow_SkFilterQuality);
} }
current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); paint.setAlpha(quad->shared_quad_state->opacity * 255);
current_paint_.setBlendMode( paint.setBlendMode(
static_cast<SkBlendMode>(quad->shared_quad_state->blend_mode)); static_cast<SkBlendMode>(quad->shared_quad_state->blend_mode));
switch (quad->material) { switch (quad->material) {
case DrawQuad::DEBUG_BORDER: case DrawQuad::DEBUG_BORDER:
DrawDebugBorderQuad(DebugBorderDrawQuad::MaterialCast(quad)); DrawDebugBorderQuad(DebugBorderDrawQuad::MaterialCast(quad), &paint);
break; break;
case DrawQuad::PICTURE_CONTENT: case DrawQuad::PICTURE_CONTENT:
DrawPictureQuad(PictureDrawQuad::MaterialCast(quad)); DrawPictureQuad(PictureDrawQuad::MaterialCast(quad), &paint);
break; break;
case DrawQuad::RENDER_PASS: case DrawQuad::RENDER_PASS:
DrawRenderPassQuad(RenderPassDrawQuad::MaterialCast(quad)); DrawRenderPassQuad(RenderPassDrawQuad::MaterialCast(quad), &paint);
break; break;
case DrawQuad::SOLID_COLOR: case DrawQuad::SOLID_COLOR:
DrawSolidColorQuad(SolidColorDrawQuad::MaterialCast(quad)); DrawSolidColorQuad(SolidColorDrawQuad::MaterialCast(quad), &paint);
break; break;
case DrawQuad::TEXTURE_CONTENT: case DrawQuad::TEXTURE_CONTENT:
DrawTextureQuad(TextureDrawQuad::MaterialCast(quad)); DrawTextureQuad(TextureDrawQuad::MaterialCast(quad), &paint);
break; break;
case DrawQuad::TILED_CONTENT: case DrawQuad::TILED_CONTENT:
NOTREACHED(); NOTREACHED();
...@@ -585,11 +584,11 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad, ...@@ -585,11 +584,11 @@ void SkiaRenderer::DoDrawQuad(const DrawQuad* quad,
NOTREACHED(); NOTREACHED();
break; break;
case DrawQuad::YUV_VIDEO_CONTENT: case DrawQuad::YUV_VIDEO_CONTENT:
DrawYUVVideoQuad(YUVVideoDrawQuad::MaterialCast(quad)); DrawYUVVideoQuad(YUVVideoDrawQuad::MaterialCast(quad), &paint);
break; break;
case DrawQuad::INVALID: case DrawQuad::INVALID:
case DrawQuad::STREAM_VIDEO_CONTENT: case DrawQuad::STREAM_VIDEO_CONTENT:
DrawUnsupportedQuad(quad); DrawUnsupportedQuad(quad, &paint);
NOTREACHED(); NOTREACHED();
break; break;
} }
...@@ -655,7 +654,9 @@ void SkiaRenderer::PrepareCanvasForDrawQuads( ...@@ -655,7 +654,9 @@ void SkiaRenderer::PrepareCanvasForDrawQuads(
} }
} }
void SkiaRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) { void SkiaRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad,
SkPaint* paint) {
DCHECK(paint);
// We need to apply the matrix manually to have pixel-sized stroke width. // We need to apply the matrix manually to have pixel-sized stroke width.
SkPoint vertices[4]; SkPoint vertices[4];
gfx::RectToSkRect(quad->rect).toQuad(vertices); gfx::RectToSkRect(quad->rect).toQuad(vertices);
...@@ -664,16 +665,17 @@ void SkiaRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) { ...@@ -664,16 +665,17 @@ void SkiaRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) {
4); 4);
current_canvas_->resetMatrix(); current_canvas_->resetMatrix();
current_paint_.setColor(quad->color); paint->setColor(quad->color);
current_paint_.setAlpha(quad->shared_quad_state->opacity * paint->setAlpha(quad->shared_quad_state->opacity * SkColorGetA(quad->color));
SkColorGetA(quad->color)); paint->setStyle(SkPaint::kStroke_Style);
current_paint_.setStyle(SkPaint::kStroke_Style); paint->setStrokeWidth(quad->width);
current_paint_.setStrokeWidth(quad->width);
current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode, 4, current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode, 4,
transformed_vertices, current_paint_); transformed_vertices, *paint);
} }
void SkiaRenderer::DrawPictureQuad(const PictureDrawQuad* quad) { void SkiaRenderer::DrawPictureQuad(const PictureDrawQuad* quad,
SkPaint* paint) {
DCHECK(paint);
SkMatrix content_matrix; SkMatrix content_matrix;
content_matrix.setRectToRect(gfx::RectFToSkRect(quad->tex_coord_rect), content_matrix.setRectToRect(gfx::RectFToSkRect(quad->tex_coord_rect),
gfx::RectToSkRect(quad->rect), gfx::RectToSkRect(quad->rect),
...@@ -718,15 +720,17 @@ void SkiaRenderer::DrawPictureQuad(const PictureDrawQuad* quad) { ...@@ -718,15 +720,17 @@ void SkiaRenderer::DrawPictureQuad(const PictureDrawQuad* quad) {
quad->display_item_list->Raster(raster_canvas); quad->display_item_list->Raster(raster_canvas);
} }
void SkiaRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad) { void SkiaRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad,
current_paint_.setColor(quad->color); SkPaint* paint) {
current_paint_.setAlpha(quad->shared_quad_state->opacity * DCHECK(paint);
SkColorGetA(quad->color)); paint->setColor(quad->color);
current_canvas_->drawRect(gfx::RectToSkRect(quad->visible_rect), paint->setAlpha(quad->shared_quad_state->opacity * SkColorGetA(quad->color));
current_paint_); current_canvas_->drawRect(gfx::RectToSkRect(quad->visible_rect), *paint);
} }
void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad) { void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad,
SkPaint* paint) {
DCHECK(paint);
ScopedSkImageBuilder builder(this, quad->resource_id()); ScopedSkImageBuilder builder(this, quad->resource_id());
const SkImage* image = builder.sk_image(); const SkImage* image = builder.sk_image();
if (!image) if (!image)
...@@ -746,21 +750,21 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad) { ...@@ -746,21 +750,21 @@ void SkiaRenderer::DrawTextureQuad(const TextureDrawQuad* quad) {
bool blend_background = bool blend_background =
quad->background_color != SK_ColorTRANSPARENT && !image->isOpaque(); quad->background_color != SK_ColorTRANSPARENT && !image->isOpaque();
bool needs_layer = blend_background && (current_paint_.getAlpha() != 0xFF); bool needs_layer = blend_background && (paint->getAlpha() != 0xFF);
base::Optional<SkAutoCanvasRestore> auto_canvas_restore; base::Optional<SkAutoCanvasRestore> auto_canvas_restore;
if (needs_layer) { if (needs_layer) {
auto_canvas_restore.emplace(current_canvas_, false /* do_save */); auto_canvas_restore.emplace(current_canvas_, false /* do_save */);
current_canvas_->saveLayerAlpha(&quad_rect, current_paint_.getAlpha()); current_canvas_->saveLayerAlpha(&quad_rect, paint->getAlpha());
current_paint_.setAlpha(0xFF); paint->setAlpha(0xFF);
} }
if (blend_background) { if (blend_background) {
SkPaint background_paint; SkPaint background_paint;
background_paint.setColor(quad->background_color); background_paint.setColor(quad->background_color);
current_canvas_->drawRect(quad_rect, background_paint); current_canvas_->drawRect(quad_rect, background_paint);
} }
current_paint_.setFilterQuality( paint->setFilterQuality(quad->nearest_neighbor ? kNone_SkFilterQuality
quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality); : kLow_SkFilterQuality);
current_canvas_->drawImageRect(image, sk_uv_rect, quad_rect, &current_paint_); current_canvas_->drawImageRect(image, sk_uv_rect, quad_rect, paint);
} }
void SkiaRenderer::AddTileQuadToBatch(const TileDrawQuad* quad, void SkiaRenderer::AddTileQuadToBatch(const TileDrawQuad* quad,
...@@ -827,7 +831,9 @@ void SkiaRenderer::DrawBatchedTileQuads() { ...@@ -827,7 +831,9 @@ void SkiaRenderer::DrawBatchedTileQuads() {
batched_tiles_.clear(); batched_tiles_.clear();
} }
void SkiaRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad) { void SkiaRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
SkPaint* paint) {
DCHECK(paint);
if (draw_mode_ != DrawMode::DDL) { if (draw_mode_ != DrawMode::DDL) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return; return;
...@@ -844,9 +850,9 @@ void SkiaRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad) { ...@@ -844,9 +850,9 @@ void SkiaRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad) {
SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect); SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect);
// TODO(penghuang): figure out how to set correct filter quality. // TODO(penghuang): figure out how to set correct filter quality.
current_paint_.setFilterQuality(kLow_SkFilterQuality); paint->setFilterQuality(kLow_SkFilterQuality);
current_canvas_->drawImageRect( current_canvas_->drawImageRect(image, uv_rect,
image, uv_rect, gfx::RectToSkRect(quad->visible_rect), &current_paint_); gfx::RectToSkRect(quad->visible_rect), paint);
} }
bool SkiaRenderer::CalculateRPDQParams(sk_sp<SkImage> content, bool SkiaRenderer::CalculateRPDQParams(sk_sp<SkImage> content,
...@@ -920,14 +926,16 @@ const TileDrawQuad* SkiaRenderer::CanPassBeDrawnDirectly( ...@@ -920,14 +926,16 @@ const TileDrawQuad* SkiaRenderer::CanPassBeDrawnDirectly(
resource_provider_); resource_provider_);
} }
void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad) { void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad,
SkPaint* paint) {
DCHECK(paint);
auto bypass = render_pass_bypass_quads_.find(quad->render_pass_id); auto bypass = render_pass_bypass_quads_.find(quad->render_pass_id);
// When Render Pass has a single quad inside we would draw that directly. // When Render Pass has a single quad inside we would draw that directly.
if (bypass != render_pass_bypass_quads_.end()) { if (bypass != render_pass_bypass_quads_.end()) {
TileDrawQuad* tile_quad = &bypass->second; TileDrawQuad* tile_quad = &bypass->second;
ScopedSkImageBuilder builder(this, tile_quad->resource_id()); ScopedSkImageBuilder builder(this, tile_quad->resource_id());
sk_sp<SkImage> content_image = sk_ref_sp(builder.sk_image()); sk_sp<SkImage> content_image = sk_ref_sp(builder.sk_image());
DrawRenderPassQuadInternal(quad, content_image); DrawRenderPassQuadInternal(quad, content_image, paint);
} else { } else {
auto iter = render_pass_backings_.find(quad->render_pass_id); auto iter = render_pass_backings_.find(quad->render_pass_id);
DCHECK(render_pass_backings_.end() != iter); DCHECK(render_pass_backings_.end() != iter);
...@@ -957,12 +965,14 @@ void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad) { ...@@ -957,12 +965,14 @@ void SkiaRenderer::DrawRenderPassQuad(const RenderPassDrawQuad* quad) {
} }
} }
DrawRenderPassQuadInternal(quad, content_image); DrawRenderPassQuadInternal(quad, content_image, paint);
} }
} }
void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad,
sk_sp<SkImage> content_image) { sk_sp<SkImage> content_image,
SkPaint* paint) {
DCHECK(paint);
DrawRenderPassDrawQuadParams params; DrawRenderPassDrawQuadParams params;
params.filters = FiltersForPass(quad->render_pass_id); params.filters = FiltersForPass(quad->render_pass_id);
bool can_draw = CalculateRPDQParams(content_image, quad, &params); bool can_draw = CalculateRPDQParams(content_image, quad, &params);
...@@ -1006,13 +1016,13 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, ...@@ -1006,13 +1016,13 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad,
if (!mask_filter) { if (!mask_filter) {
// Not mask, so we just draw the context_image directly. // Not mask, so we just draw the context_image directly.
current_canvas_->drawImageRect(content_image, content_rect, current_canvas_->drawImageRect(content_image, content_rect,
dest_visible_rect, &current_paint_); dest_visible_rect, paint);
return; return;
} }
// With mask, we need convert the content_image to a shader, and use // With mask, we need convert the content_image to a shader, and use
// drawRect() with the shader and the mask. // drawRect() with the shader and the mask.
current_paint_.setMaskFilter(mask_filter); paint->setMaskFilter(mask_filter);
// Convert the content_image to a shader, and use drawRect() with the // Convert the content_image to a shader, and use drawRect() with the
// shader. // shader.
SkMatrix content_to_dest_matrix; SkMatrix content_to_dest_matrix;
...@@ -1020,8 +1030,8 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, ...@@ -1020,8 +1030,8 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad,
gfx::RectToSkRect(quad->rect), gfx::RectToSkRect(quad->rect),
SkMatrix::kFill_ScaleToFit); SkMatrix::kFill_ScaleToFit);
auto shader = content_image->makeShader(&content_to_dest_matrix); auto shader = content_image->makeShader(&content_to_dest_matrix);
current_paint_.setShader(std::move(shader)); paint->setShader(std::move(shader));
current_canvas_->drawRect(dest_visible_rect, current_paint_); current_canvas_->drawRect(dest_visible_rect, *paint);
return; return;
} }
...@@ -1046,9 +1056,9 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, ...@@ -1046,9 +1056,9 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad,
SkAutoCanvasRestore auto_canvas_restore(current_canvas_, true /* do_save */); SkAutoCanvasRestore auto_canvas_restore(current_canvas_, true /* do_save */);
current_canvas_->clipRect(gfx::RectToSkRect(quad->rect)); current_canvas_->clipRect(gfx::RectToSkRect(quad->rect));
SkPaint paint; SkPaint tmp_paint;
paint.setMaskFilter(mask_filter); tmp_paint.setMaskFilter(mask_filter);
SkCanvas::SaveLayerRec rec(&dest_visible_rect, &paint, SkCanvas::SaveLayerRec rec(&dest_visible_rect, &tmp_paint,
background_image_filter.get(), background_image_filter.get(),
SkCanvas::kInitWithPrevious_SaveLayerFlag); SkCanvas::kInitWithPrevious_SaveLayerFlag);
// Lift content in the current_canvas_ into a new layer with // Lift content in the current_canvas_ into a new layer with
...@@ -1059,19 +1069,20 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, ...@@ -1059,19 +1069,20 @@ void SkiaRenderer::DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad,
false /* do_save */); false /* do_save */);
current_canvas_->saveLayer(rec); current_canvas_->saveLayer(rec);
current_canvas_->drawImageRect(content_image, content_rect, dest_visible_rect, current_canvas_->drawImageRect(content_image, content_rect, dest_visible_rect,
&current_paint_); paint);
} }
void SkiaRenderer::DrawUnsupportedQuad(const DrawQuad* quad) { void SkiaRenderer::DrawUnsupportedQuad(const DrawQuad* quad, SkPaint* paint) {
DCHECK(paint);
// TODO(weiliangc): Make sure unsupported quads work. (crbug.com/644851) // TODO(weiliangc): Make sure unsupported quads work. (crbug.com/644851)
NOTIMPLEMENTED(); NOTIMPLEMENTED();
#ifdef NDEBUG #ifdef NDEBUG
current_paint_.setColor(SK_ColorWHITE); paint->setColor(SK_ColorWHITE);
#else #else
current_paint_.setColor(SK_ColorMAGENTA); paint->setColor(SK_ColorMAGENTA);
#endif #endif
current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); paint->setAlpha(quad->shared_quad_state->opacity * 255);
current_canvas_->drawRect(gfx::RectToSkRect(quad->rect), current_paint_); current_canvas_->drawRect(gfx::RectToSkRect(quad->rect), *paint);
} }
void SkiaRenderer::CopyDrawnRenderPass( void SkiaRenderer::CopyDrawnRenderPass(
......
...@@ -96,21 +96,22 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer { ...@@ -96,21 +96,22 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
const gfx::QuadF* draw_region, const gfx::QuadF* draw_region,
const gfx::Rect* scissor_rect, const gfx::Rect* scissor_rect,
base::Optional<SkAutoCanvasRestore>* auto_canvas_restore); base::Optional<SkAutoCanvasRestore>* auto_canvas_restore);
void DrawDebugBorderQuad(const DebugBorderDrawQuad* quad); void DrawDebugBorderQuad(const DebugBorderDrawQuad* quad, SkPaint* paint);
void DrawPictureQuad(const PictureDrawQuad* quad); void DrawPictureQuad(const PictureDrawQuad* quad, SkPaint* paint);
void DrawRenderPassQuad(const RenderPassDrawQuad* quad); void DrawRenderPassQuad(const RenderPassDrawQuad* quad, SkPaint* paint);
void DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad, void DrawRenderPassQuadInternal(const RenderPassDrawQuad* quad,
sk_sp<SkImage> content_image); sk_sp<SkImage> content_image,
SkPaint* paint);
void DrawSolidColorQuad(const SolidColorDrawQuad* quad); void DrawSolidColorQuad(const SolidColorDrawQuad* quad, SkPaint* paint);
void DrawTextureQuad(const TextureDrawQuad* quad); void DrawTextureQuad(const TextureDrawQuad* quad, SkPaint* paint);
bool MustDrawBatchedTileQuadsBeforeQuad(const DrawQuad* new_quad, bool MustDrawBatchedTileQuadsBeforeQuad(const DrawQuad* new_quad,
const gfx::QuadF* draw_region); const gfx::QuadF* draw_region);
void AddTileQuadToBatch(const TileDrawQuad* quad, void AddTileQuadToBatch(const TileDrawQuad* quad,
const gfx::QuadF* draw_region); const gfx::QuadF* draw_region);
void DrawBatchedTileQuads(); void DrawBatchedTileQuads();
void DrawYUVVideoQuad(const YUVVideoDrawQuad* quad); void DrawYUVVideoQuad(const YUVVideoDrawQuad* quad, SkPaint* paint);
void DrawUnsupportedQuad(const DrawQuad* quad); void DrawUnsupportedQuad(const DrawQuad* quad, SkPaint* paint);
bool CalculateRPDQParams(sk_sp<SkImage> src_image, bool CalculateRPDQParams(sk_sp<SkImage> src_image,
const RenderPassDrawQuad* quad, const RenderPassDrawQuad* quad,
DrawRenderPassDrawQuadParams* params); DrawRenderPassDrawQuadParams* params);
...@@ -164,7 +165,6 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer { ...@@ -164,7 +165,6 @@ class VIZ_SERVICE_EXPORT SkiaRenderer : public DirectRenderer {
bool disable_picture_quad_image_filtering_ = false; bool disable_picture_quad_image_filtering_ = false;
bool is_scissor_enabled_ = false; bool is_scissor_enabled_ = false;
gfx::Rect scissor_rect_; gfx::Rect scissor_rect_;
SkPaint current_paint_;
// Specific for overdraw. // Specific for overdraw.
sk_sp<SkSurface> overdraw_surface_; sk_sp<SkSurface> overdraw_surface_;
......
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