Commit 7440d469 authored by Vladimir Levin's avatar Vladimir Levin Committed by Commit Bot

Plumb PaintImage into PaintShaders.

This patch plumbs PaintImage into PaintShaders instead of SkImage.
With the patch to not construct SkPaint and instead using PaintFlags,
it becomes possible to introspect the flags to pull off PaintImage used
to construct it.

R=khushalsagar@chromium.org, chrishtr@chromium.org

Change-Id: Ia01ce40b1586b90172421ba99009baeb604fd937
Reviewed-on: https://chromium-review.googlesource.com/576868Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatardanakj <danakj@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488812}
parent b2724284
...@@ -579,8 +579,8 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInShader) { ...@@ -579,8 +579,8 @@ TEST_F(DiscardableImageMapTest, GetDiscardableImagesInShader) {
std::max(y * 0.5f, kMinScale)); std::max(y * 0.5f, kMinScale));
PaintFlags flags; PaintFlags flags;
flags.setShader(PaintShader::MakeImage( flags.setShader(PaintShader::MakeImage(
discardable_image[y][x], SkShader::kClamp_TileMode, PaintImage(y * 4 + x, discardable_image[y][x]),
SkShader::kClamp_TileMode, &scale)); SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &scale));
content_layer_client.add_draw_rect( content_layer_client.add_draw_rect(
gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), flags); gfx::Rect(x * 512 + 6, y * 512 + 6, 500, 500), flags);
} }
......
...@@ -42,4 +42,10 @@ PaintImage::Id PaintImage::GetNextId() { ...@@ -42,4 +42,10 @@ PaintImage::Id PaintImage::GetNextId() {
return s_next_id_.GetNext(); return s_next_id_.GetNext();
} }
PaintImage PaintImage::CloneWithSkImage(sk_sp<SkImage> new_image) const {
PaintImage result(*this);
result.sk_image_ = std::move(new_image);
return result;
}
} // namespace cc } // namespace cc
...@@ -64,6 +64,11 @@ class CC_PAINT_EXPORT PaintImage { ...@@ -64,6 +64,11 @@ class CC_PAINT_EXPORT PaintImage {
size_t frame_count() const { return frame_count_; } size_t frame_count() const { return frame_count_; }
bool is_multipart() const { return is_multipart_; } bool is_multipart() const { return is_multipart_; }
// Returns a PaintImage that has the same fields as this PaintImage, except
// with a replaced sk_image_. This can be used to swap out a specific SkImage
// in an otherwise unchanged PaintImage.
PaintImage CloneWithSkImage(sk_sp<SkImage> new_image) const;
private: private:
Id id_ = kUnknownStableId; Id id_ = kUnknownStableId;
sk_sp<SkImage> sk_image_; sk_sp<SkImage> sk_image_;
......
...@@ -475,7 +475,8 @@ TEST(PaintOpBufferTest, DiscardableImagesTracking_DrawImageRect) { ...@@ -475,7 +475,8 @@ TEST(PaintOpBufferTest, DiscardableImagesTracking_DrawImageRect) {
TEST(PaintOpBufferTest, DiscardableImagesTracking_OpWithFlags) { TEST(PaintOpBufferTest, DiscardableImagesTracking_OpWithFlags) {
PaintOpBuffer buffer; PaintOpBuffer buffer;
PaintFlags flags; PaintFlags flags;
sk_sp<SkImage> image = CreateDiscardableImage(gfx::Size(100, 100)); auto image = PaintImage(PaintImage::GetNextId(),
CreateDiscardableImage(gfx::Size(100, 100)));
flags.setShader(PaintShader::MakeImage(std::move(image), flags.setShader(PaintShader::MakeImage(std::move(image),
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode, nullptr)); SkShader::kClamp_TileMode, nullptr));
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
namespace cc { namespace cc {
sk_sp<PaintShader> PaintShader::MakeColor(SkColor color) { sk_sp<PaintShader> PaintShader::MakeColor(SkColor color) {
sk_sp<PaintShader> shader(new PaintShader(kColor)); sk_sp<PaintShader> shader(new PaintShader(Type::kColor));
// Just one color. Store it in the fallback color. Easy. // Just one color. Store it in the fallback color. Easy.
shader->fallback_color_ = color; shader->fallback_color_ = color;
...@@ -27,7 +27,7 @@ sk_sp<PaintShader> PaintShader::MakeLinearGradient(const SkPoint points[], ...@@ -27,7 +27,7 @@ sk_sp<PaintShader> PaintShader::MakeLinearGradient(const SkPoint points[],
uint32_t flags, uint32_t flags,
const SkMatrix* local_matrix, const SkMatrix* local_matrix,
SkColor fallback_color) { SkColor fallback_color) {
sk_sp<PaintShader> shader(new PaintShader(kLinearGradient)); sk_sp<PaintShader> shader(new PaintShader(Type::kLinearGradient));
// There are always two points, the start and the end. // There are always two points, the start and the end.
shader->start_point_ = points[0]; shader->start_point_ = points[0];
...@@ -48,7 +48,7 @@ sk_sp<PaintShader> PaintShader::MakeRadialGradient(const SkPoint& center, ...@@ -48,7 +48,7 @@ sk_sp<PaintShader> PaintShader::MakeRadialGradient(const SkPoint& center,
uint32_t flags, uint32_t flags,
const SkMatrix* local_matrix, const SkMatrix* local_matrix,
SkColor fallback_color) { SkColor fallback_color) {
sk_sp<PaintShader> shader(new PaintShader(kRadialGradient)); sk_sp<PaintShader> shader(new PaintShader(Type::kRadialGradient));
shader->center_ = center; shader->center_ = center;
shader->start_radius_ = shader->end_radius_ = radius; shader->start_radius_ = shader->end_radius_ = radius;
...@@ -71,7 +71,7 @@ sk_sp<PaintShader> PaintShader::MakeTwoPointConicalGradient( ...@@ -71,7 +71,7 @@ sk_sp<PaintShader> PaintShader::MakeTwoPointConicalGradient(
uint32_t flags, uint32_t flags,
const SkMatrix* local_matrix, const SkMatrix* local_matrix,
SkColor fallback_color) { SkColor fallback_color) {
sk_sp<PaintShader> shader(new PaintShader(kTwoPointConicalGradient)); sk_sp<PaintShader> shader(new PaintShader(Type::kTwoPointConicalGradient));
shader->start_point_ = start; shader->start_point_ = start;
shader->end_point_ = end; shader->end_point_ = end;
...@@ -92,7 +92,7 @@ sk_sp<PaintShader> PaintShader::MakeSweepGradient(SkScalar cx, ...@@ -92,7 +92,7 @@ sk_sp<PaintShader> PaintShader::MakeSweepGradient(SkScalar cx,
uint32_t flags, uint32_t flags,
const SkMatrix* local_matrix, const SkMatrix* local_matrix,
SkColor fallback_color) { SkColor fallback_color) {
sk_sp<PaintShader> shader(new PaintShader(kSweepGradient)); sk_sp<PaintShader> shader(new PaintShader(Type::kSweepGradient));
shader->center_ = SkPoint::Make(cx, cy); shader->center_ = SkPoint::Make(cx, cy);
shader->SetColorsAndPositions(colors, pos, color_count); shader->SetColorsAndPositions(colors, pos, color_count);
...@@ -103,27 +103,30 @@ sk_sp<PaintShader> PaintShader::MakeSweepGradient(SkScalar cx, ...@@ -103,27 +103,30 @@ sk_sp<PaintShader> PaintShader::MakeSweepGradient(SkScalar cx,
return shader; return shader;
} }
sk_sp<PaintShader> PaintShader::MakeImage(sk_sp<const SkImage> image, sk_sp<PaintShader> PaintShader::MakeImage(const PaintImage& image,
SkShader::TileMode tx, SkShader::TileMode tx,
SkShader::TileMode ty, SkShader::TileMode ty,
const SkMatrix* local_matrix) { const SkMatrix* local_matrix) {
sk_sp<PaintShader> shader(new PaintShader(kImage)); sk_sp<PaintShader> shader(new PaintShader(Type::kImage));
shader->image_ = std::move(image); shader->image_ = image;
shader->SetMatrixAndTiling(local_matrix, tx, ty); shader->SetMatrixAndTiling(local_matrix, tx, ty);
return shader; return shader;
} }
sk_sp<PaintShader> PaintShader::MakePaintRecord(sk_sp<PaintRecord> record, sk_sp<PaintShader> PaintShader::MakePaintRecord(
const SkRect& tile, sk_sp<PaintRecord> record,
SkShader::TileMode tx, const SkRect& tile,
SkShader::TileMode ty, SkShader::TileMode tx,
const SkMatrix* local_matrix) { SkShader::TileMode ty,
sk_sp<PaintShader> shader(new PaintShader(kPaintRecord)); const SkMatrix* local_matrix,
ScalingBehavior scaling_behavior) {
sk_sp<PaintShader> shader(new PaintShader(Type::kPaintRecord));
shader->record_ = std::move(record); shader->record_ = std::move(record);
shader->tile_ = tile; shader->tile_ = tile;
shader->scaling_behavior_ = scaling_behavior;
shader->SetMatrixAndTiling(local_matrix, tx, ty); shader->SetMatrixAndTiling(local_matrix, tx, ty);
return shader; return shader;
...@@ -137,10 +140,10 @@ sk_sp<SkShader> PaintShader::GetSkShader() const { ...@@ -137,10 +140,10 @@ sk_sp<SkShader> PaintShader::GetSkShader() const {
return cached_shader_; return cached_shader_;
switch (shader_type_) { switch (shader_type_) {
case kColor: case Type::kColor:
// This will be handled by the fallback check below. // This will be handled by the fallback check below.
break; break;
case kLinearGradient: { case Type::kLinearGradient: {
SkPoint points[2] = {start_point_, end_point_}; SkPoint points[2] = {start_point_, end_point_};
cached_shader_ = SkGradientShader::MakeLinear( cached_shader_ = SkGradientShader::MakeLinear(
points, colors_.data(), points, colors_.data(),
...@@ -149,37 +152,56 @@ sk_sp<SkShader> PaintShader::GetSkShader() const { ...@@ -149,37 +152,56 @@ sk_sp<SkShader> PaintShader::GetSkShader() const {
local_matrix_ ? &*local_matrix_ : nullptr); local_matrix_ ? &*local_matrix_ : nullptr);
break; break;
} }
case kRadialGradient: case Type::kRadialGradient:
cached_shader_ = SkGradientShader::MakeRadial( cached_shader_ = SkGradientShader::MakeRadial(
center_, start_radius_, colors_.data(), center_, start_radius_, colors_.data(),
positions_.empty() ? nullptr : positions_.data(), positions_.empty() ? nullptr : positions_.data(),
static_cast<int>(colors_.size()), tx_, flags_, static_cast<int>(colors_.size()), tx_, flags_,
local_matrix_ ? &*local_matrix_ : nullptr); local_matrix_ ? &*local_matrix_ : nullptr);
break; break;
case kTwoPointConicalGradient: case Type::kTwoPointConicalGradient:
cached_shader_ = SkGradientShader::MakeTwoPointConical( cached_shader_ = SkGradientShader::MakeTwoPointConical(
start_point_, start_radius_, end_point_, end_radius_, colors_.data(), start_point_, start_radius_, end_point_, end_radius_, colors_.data(),
positions_.empty() ? nullptr : positions_.data(), positions_.empty() ? nullptr : positions_.data(),
static_cast<int>(colors_.size()), tx_, flags_, static_cast<int>(colors_.size()), tx_, flags_,
local_matrix_ ? &*local_matrix_ : nullptr); local_matrix_ ? &*local_matrix_ : nullptr);
break; break;
case kSweepGradient: case Type::kSweepGradient:
cached_shader_ = SkGradientShader::MakeSweep( cached_shader_ = SkGradientShader::MakeSweep(
center_.x(), center_.y(), colors_.data(), center_.x(), center_.y(), colors_.data(),
positions_.empty() ? nullptr : positions_.data(), positions_.empty() ? nullptr : positions_.data(),
static_cast<int>(colors_.size()), flags_, static_cast<int>(colors_.size()), flags_,
local_matrix_ ? &*local_matrix_ : nullptr); local_matrix_ ? &*local_matrix_ : nullptr);
break; break;
case kImage: case Type::kImage:
cached_shader_ = image_->makeShader( cached_shader_ = image_.sk_image()->makeShader(
tx_, ty_, local_matrix_ ? &*local_matrix_ : nullptr); tx_, ty_, local_matrix_ ? &*local_matrix_ : nullptr);
break; break;
case kPaintRecord: case Type::kPaintRecord: {
cached_shader_ = SkShader::MakePictureShader( auto picture = ToSkPicture(record_, tile_);
ToSkPicture(record_, tile_), tx_, ty_,
local_matrix_ ? &*local_matrix_ : nullptr, nullptr); switch (scaling_behavior_) {
// For raster scale, we create a picture shader directly.
case ScalingBehavior::kRasterAtScale:
cached_shader_ = SkShader::MakePictureShader(
std::move(picture), tx_, ty_,
local_matrix_ ? &*local_matrix_ : nullptr, nullptr);
break;
// For fixed scale, we create an image shader with and image backed by
// the picture.
case ScalingBehavior::kFixedScale: {
auto image = SkImage::MakeFromPicture(
std::move(picture), SkISize::Make(tile_.width(), tile_.height()),
nullptr, nullptr, SkImage::BitDepth::kU8,
SkColorSpace::MakeSRGB());
cached_shader_ = image->makeShader(
tx_, ty_, local_matrix_ ? &*local_matrix_ : nullptr);
break;
}
}
break; break;
case kShaderCount: }
case Type::kShaderCount:
NOTREACHED(); NOTREACHED();
break; break;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "cc/paint/paint_export.h" #include "cc/paint/paint_export.h"
#include "cc/paint/paint_image.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkScalar.h" #include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/core/SkShader.h"
...@@ -21,6 +22,22 @@ using PaintRecord = PaintOpBuffer; ...@@ -21,6 +22,22 @@ using PaintRecord = PaintOpBuffer;
class CC_PAINT_EXPORT PaintShader : public SkRefCnt { class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
public: public:
enum class Type {
kColor,
kLinearGradient,
kRadialGradient,
kTwoPointConicalGradient,
kSweepGradient,
kImage,
kPaintRecord,
kShaderCount
};
// Scaling behavior dictates how a PaintRecord shader will behave. Use
// RasterAtScale to create a picture shader. Use FixedScale to create an image
// shader that is backed by the paint record.
enum class ScalingBehavior { kRasterAtScale, kFixedScale };
static sk_sp<PaintShader> MakeColor(SkColor color); static sk_sp<PaintShader> MakeColor(SkColor color);
static sk_sp<PaintShader> MakeLinearGradient( static sk_sp<PaintShader> MakeLinearGradient(
...@@ -67,39 +84,35 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt { ...@@ -67,39 +84,35 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
const SkMatrix* local_matrix = nullptr, const SkMatrix* local_matrix = nullptr,
SkColor fallback_color = SK_ColorTRANSPARENT); SkColor fallback_color = SK_ColorTRANSPARENT);
static sk_sp<PaintShader> MakeImage(sk_sp<const SkImage> image, static sk_sp<PaintShader> MakeImage(const PaintImage& image,
SkShader::TileMode tx, SkShader::TileMode tx,
SkShader::TileMode ty, SkShader::TileMode ty,
const SkMatrix* local_matrix); const SkMatrix* local_matrix);
static sk_sp<PaintShader> MakePaintRecord(sk_sp<PaintRecord> record, static sk_sp<PaintShader> MakePaintRecord(
const SkRect& tile, sk_sp<PaintRecord> record,
SkShader::TileMode tx, const SkRect& tile,
SkShader::TileMode ty, SkShader::TileMode tx,
const SkMatrix* local_matrix); SkShader::TileMode ty,
const SkMatrix* local_matrix,
ScalingBehavior scaling_behavior = ScalingBehavior::kRasterAtScale);
~PaintShader() override; ~PaintShader() override;
SkMatrix GetLocalMatrix() const { SkMatrix GetLocalMatrix() const {
return local_matrix_ ? *local_matrix_ : SkMatrix::I(); return local_matrix_ ? *local_matrix_ : SkMatrix::I();
} }
Type shader_type() const { return shader_type_; }
const PaintImage& paint_image() {
DCHECK_EQ(Type::kImage, shader_type_);
return image_;
}
bool IsOpaque() const; bool IsOpaque() const;
private: private:
friend class PaintFlags; friend class PaintFlags;
enum Type {
kColor,
kLinearGradient,
kRadialGradient,
kTwoPointConicalGradient,
kSweepGradient,
kImage,
kPaintRecord,
kShaderCount
};
explicit PaintShader(Type type); explicit PaintShader(Type type);
sk_sp<SkShader> GetSkShader() const; sk_sp<SkShader> GetSkShader() const;
...@@ -112,7 +125,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt { ...@@ -112,7 +125,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
SkShader::TileMode ty); SkShader::TileMode ty);
void SetFlagsAndFallback(uint32_t flags, SkColor fallback_color); void SetFlagsAndFallback(uint32_t flags, SkColor fallback_color);
Type shader_type_ = kShaderCount; Type shader_type_ = Type::kShaderCount;
uint32_t flags_ = 0; uint32_t flags_ = 0;
SkScalar end_radius_ = 0; SkScalar end_radius_ = 0;
...@@ -120,6 +133,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt { ...@@ -120,6 +133,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
SkShader::TileMode tx_ = SkShader::kClamp_TileMode; SkShader::TileMode tx_ = SkShader::kClamp_TileMode;
SkShader::TileMode ty_ = SkShader::kClamp_TileMode; SkShader::TileMode ty_ = SkShader::kClamp_TileMode;
SkColor fallback_color_ = SK_ColorTRANSPARENT; SkColor fallback_color_ = SK_ColorTRANSPARENT;
ScalingBehavior scaling_behavior_ = ScalingBehavior::kRasterAtScale;
base::Optional<SkMatrix> local_matrix_; base::Optional<SkMatrix> local_matrix_;
SkPoint center_ = SkPoint::Make(0, 0); SkPoint center_ = SkPoint::Make(0, 0);
...@@ -128,7 +142,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt { ...@@ -128,7 +142,7 @@ class CC_PAINT_EXPORT PaintShader : public SkRefCnt {
SkPoint start_point_ = SkPoint::Make(0, 0); SkPoint start_point_ = SkPoint::Make(0, 0);
SkPoint end_point_ = SkPoint::Make(0, 0); SkPoint end_point_ = SkPoint::Make(0, 0);
sk_sp<const SkImage> image_; PaintImage image_;
sk_sp<PaintRecord> record_; sk_sp<PaintRecord> record_;
std::vector<SkColor> colors_; std::vector<SkColor> colors_;
......
...@@ -123,9 +123,7 @@ PaintImage DragImage::ResizeAndOrientImage( ...@@ -123,9 +123,7 @@ PaintImage DragImage::ResizeAndOrientImage(
canvas->concat(AffineTransformToSkMatrix(transform)); canvas->concat(AffineTransformToSkMatrix(transform));
canvas->drawImage(image.sk_image(), 0, 0, &paint); canvas->drawImage(image.sk_image(), 0, 0, &paint);
return PaintImage(image.stable_id(), surface->makeImageSnapshot(), return image.CloneWithSkImage(surface->makeImageSnapshot());
image.animation_type(), image.completion_state(),
image.frame_count());
} }
FloatSize DragImage::ClampedImageScale(const IntSize& image_size, FloatSize DragImage::ClampedImageScale(const IntSize& image_size,
......
...@@ -241,7 +241,7 @@ sk_sp<PaintShader> CreatePatternShader(const PaintImage& image, ...@@ -241,7 +241,7 @@ sk_sp<PaintShader> CreatePatternShader(const PaintImage& image,
SkShader::TileMode tmx, SkShader::TileMode tmx,
SkShader::TileMode tmy) { SkShader::TileMode tmy) {
if (spacing.IsZero()) { if (spacing.IsZero()) {
return PaintShader::MakeImage(image.sk_image(), tmx, tmy, &shader_matrix); return PaintShader::MakeImage(image, tmx, tmy, &shader_matrix);
} }
// Arbitrary tiling is currently only supported for SkPictureShader, so we use // Arbitrary tiling is currently only supported for SkPictureShader, so we use
...@@ -363,13 +363,13 @@ PaintImage Image::PaintImageForCurrentFrame() { ...@@ -363,13 +363,13 @@ PaintImage Image::PaintImageForCurrentFrame() {
bool Image::ApplyShader(PaintFlags& flags, const SkMatrix& local_matrix) { bool Image::ApplyShader(PaintFlags& flags, const SkMatrix& local_matrix) {
// Default shader impl: attempt to build a shader based on the current frame // Default shader impl: attempt to build a shader based on the current frame
// SkImage. // SkImage.
sk_sp<SkImage> image = ImageForCurrentFrame(); PaintImage image = PaintImageForCurrentFrame();
if (!image) if (!image)
return false; return false;
flags.setShader( flags.setShader(PaintShader::MakeImage(image, SkShader::kRepeat_TileMode,
PaintShader::MakeImage(std::move(image), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
SkShader::kRepeat_TileMode, &local_matrix)); &local_matrix));
if (!flags.HasShader()) if (!flags.HasShader())
return false; return false;
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
#include "platform/graphics/ImagePattern.h" #include "platform/graphics/ImagePattern.h"
#include "platform/graphics/Image.h" #include "platform/graphics/Image.h"
#include "platform/graphics/paint/PaintRecorder.h"
#include "platform/graphics/paint/PaintShader.h" #include "platform/graphics/paint/PaintShader.h"
#include "platform/graphics/skia/SkiaUtils.h" #include "platform/graphics/skia/SkiaUtils.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
namespace blink { namespace blink {
...@@ -19,7 +19,7 @@ PassRefPtr<ImagePattern> ImagePattern::Create(PassRefPtr<Image> image, ...@@ -19,7 +19,7 @@ PassRefPtr<ImagePattern> ImagePattern::Create(PassRefPtr<Image> image,
} }
ImagePattern::ImagePattern(PassRefPtr<Image> image, RepeatMode repeat_mode) ImagePattern::ImagePattern(PassRefPtr<Image> image, RepeatMode repeat_mode)
: Pattern(repeat_mode), tile_image_(image->ImageForCurrentFrame()) { : Pattern(repeat_mode), tile_image_(image->PaintImageForCurrentFrame()) {
previous_local_matrix_.setIdentity(); previous_local_matrix_.setIdentity();
} }
...@@ -54,32 +54,29 @@ sk_sp<PaintShader> ImagePattern::CreateShader(const SkMatrix& local_matrix) { ...@@ -54,32 +54,29 @@ sk_sp<PaintShader> ImagePattern::CreateShader(const SkMatrix& local_matrix) {
// Create a transparent image 2 pixels wider and/or taller than the // Create a transparent image 2 pixels wider and/or taller than the
// original, then copy the orignal into the middle of it. // original, then copy the orignal into the middle of it.
const SkISize tile_size = const SkRect tile_bounds =
SkISize::Make(tile_image_->width() + 2 * border_pixel_x, SkRect::MakeWH(tile_image_.sk_image()->width() + 2 * border_pixel_x,
tile_image_->height() + 2 * border_pixel_y); tile_image_.sk_image()->height() + 2 * border_pixel_y);
SkPictureRecorder recorder; PaintRecorder recorder;
recorder.beginRecording(tile_size.width(), tile_size.height()); auto* canvas = recorder.beginRecording(tile_bounds);
SkPaint paint; PaintFlags paint;
paint.setBlendMode(SkBlendMode::kSrc); paint.setBlendMode(SkBlendMode::kSrc);
recorder.getRecordingCanvas()->drawImage(tile_image_, border_pixel_x, canvas->drawImage(tile_image_, border_pixel_x, border_pixel_y, &paint);
border_pixel_y, &paint);
// Note: we use a picture *image* (as opposed to a picture *shader*) to
// lock-in the resolution (for 1px padding in particular).
sk_sp<SkImage> tile_image = SkImage::MakeFromPicture(
recorder.finishRecordingAsPicture(), tile_size, nullptr, nullptr,
SkImage::BitDepth::kU8, SkColorSpace::MakeSRGB());
previous_local_matrix_ = local_matrix; previous_local_matrix_ = local_matrix;
SkMatrix adjusted_matrix(local_matrix); SkMatrix adjusted_matrix(local_matrix);
adjusted_matrix.postTranslate(-border_pixel_x, -border_pixel_y); adjusted_matrix.postTranslate(-border_pixel_x, -border_pixel_y);
return PaintShader::MakeImage(std::move(tile_image), tile_mode_x, tile_mode_y, // Note: we specify kFixedScale to lock-in the resolution (for 1px padding in
&adjusted_matrix); // particular).
return PaintShader::MakePaintRecord(
recorder.finishRecordingAsPicture(), tile_bounds, tile_mode_x,
tile_mode_y, &adjusted_matrix, PaintShader::ScalingBehavior::kFixedScale);
} }
bool ImagePattern::IsTextureBacked() const { bool ImagePattern::IsTextureBacked() const {
return tile_image_ && tile_image_->isTextureBacked(); return tile_image_.sk_image() && tile_image_.sk_image()->isTextureBacked();
} }
} // namespace blink } // namespace blink
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
#define ImagePattern_h #define ImagePattern_h
#include "platform/graphics/Pattern.h" #include "platform/graphics/Pattern.h"
#include "platform/graphics/paint/PaintImage.h"
class SkImage;
namespace blink { namespace blink {
...@@ -27,7 +26,7 @@ class PLATFORM_EXPORT ImagePattern final : public Pattern { ...@@ -27,7 +26,7 @@ class PLATFORM_EXPORT ImagePattern final : public Pattern {
ImagePattern(PassRefPtr<Image>, RepeatMode); ImagePattern(PassRefPtr<Image>, RepeatMode);
SkMatrix previous_local_matrix_; SkMatrix previous_local_matrix_;
sk_sp<SkImage> tile_image_; PaintImage tile_image_;
}; };
} // namespace blink } // namespace blink
......
...@@ -38,8 +38,9 @@ sk_sp<cc::PaintShader> CreateImageRepShaderForScale( ...@@ -38,8 +38,9 @@ sk_sp<cc::PaintShader> CreateImageRepShaderForScale(
shader_scale.setScaleY(local_matrix.getScaleY() / scale); shader_scale.setScaleY(local_matrix.getScaleY() / scale);
return cc::PaintShader::MakeImage( return cc::PaintShader::MakeImage(
SkImage::MakeFromBitmap(image_rep.sk_bitmap()), tile_mode, tile_mode, cc::PaintImage(cc::PaintImage::kNonLazyStableId,
&shader_scale); SkImage::MakeFromBitmap(image_rep.sk_bitmap())),
tile_mode, tile_mode, &shader_scale);
} }
sk_sp<cc::PaintShader> CreateGradientShader(int start_point, sk_sp<cc::PaintShader> CreateGradientShader(int start_point,
......
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