summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreed <reed@google.com>2015-08-28 06:43:25 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-28 13:43:50 +0000
commit47c0625da08aa28d4fc8c0743ac7bab5739346d0 (patch)
tree7b5161683cc3f413e3d20fb73e67c057c4f6cb4e
parent25b4f71939bcb300e586eefc4bcf5c0fe5cb81a7 (diff)
downloadchromium_src-47c0625da08aa28d4fc8c0743ac7bab5739346d0.zip
chromium_src-47c0625da08aa28d4fc8c0743ac7bab5739346d0.tar.gz
chromium_src-47c0625da08aa28d4fc8c0743ac7bab5739346d0.tar.bz2
clone pixel_ref_utils into discardable_image_utils, since blink now creates images instead of bitmaps. When this is in place, we can remove pixel_ref_utils.
BUG= Review URL: https://codereview.chromium.org/1306293004 Cr-Commit-Position: refs/heads/master@{#346134}
-rw-r--r--skia/ext/discardable_image_utils.cc134
-rw-r--r--skia/ext/discardable_image_utils.h33
-rw-r--r--skia/ext/discardable_image_utils_unittest.cc185
-rw-r--r--skia/skia_chrome.gypi1
-rw-r--r--skia/skia_tests.gyp1
5 files changed, 354 insertions, 0 deletions
diff --git a/skia/ext/discardable_image_utils.cc b/skia/ext/discardable_image_utils.cc
new file mode 100644
index 0000000..f447ff9
--- /dev/null
+++ b/skia/ext/discardable_image_utils.cc
@@ -0,0 +1,134 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "skia/ext/discardable_image_utils.h"
+
+#include <algorithm>
+
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/utils/SkNWayCanvas.h"
+
+namespace skia {
+
+namespace {
+
+class DiscardableImageSet {
+ public:
+ DiscardableImageSet(std::vector<DiscardableImageUtils::PositionImage>* images)
+ : images_(images) {}
+
+ void Add(const SkImage* image,
+ const SkRect& rect,
+ const SkMatrix& matrix,
+ SkFilterQuality filter_quality) {
+ // We should only be saving discardable pixel refs.
+ SkASSERT(image->isLazyGenerated());
+
+ DiscardableImageUtils::PositionImage position_image;
+ position_image.image = image;
+ position_image.image_rect = rect;
+ position_image.matrix = matrix;
+ position_image.filter_quality = filter_quality;
+ images_->push_back(position_image);
+ }
+
+ private:
+ std::vector<DiscardableImageUtils::PositionImage>* images_;
+};
+
+SkRect MapRect(const SkMatrix& matrix, const SkRect& src) {
+ SkRect dst;
+ matrix.mapRect(&dst, src);
+ return dst;
+}
+
+class GatherDiscardableImageCanvas : public SkNWayCanvas {
+ public:
+ GatherDiscardableImageCanvas(int width,
+ int height,
+ DiscardableImageSet* image_set)
+ : SkNWayCanvas(width, height),
+ image_set_(image_set),
+ canvas_bounds_(SkRect::MakeIWH(width, height)) {}
+
+ protected:
+ // we need to "undo" the behavio of SkNWayCanvas, which will try to forward
+ // it.
+ void onDrawPicture(const SkPicture* picture,
+ const SkMatrix* matrix,
+ const SkPaint* paint) override {
+ SkCanvas::onDrawPicture(picture, matrix, paint);
+ }
+
+ void onDrawImage(const SkImage* image,
+ SkScalar x,
+ SkScalar y,
+ const SkPaint* paint) override {
+ const SkMatrix& ctm = this->getTotalMatrix();
+ AddImage(image, MapRect(ctm, SkRect::MakeXYWH(x, y, image->width(),
+ image->height())),
+ ctm, paint);
+ }
+
+ void onDrawImageRect(const SkImage* image,
+ const SkRect* src,
+ const SkRect& dst,
+ const SkPaint* paint,
+ SrcRectConstraint) override {
+ const SkMatrix& ctm = this->getTotalMatrix();
+ SkRect src_storage;
+ if (!src) {
+ src_storage = SkRect::MakeIWH(image->width(), image->height());
+ src = &src_storage;
+ }
+ SkMatrix matrix;
+ matrix.setRectToRect(*src, dst, SkMatrix::kFill_ScaleToFit);
+ matrix.postConcat(ctm);
+ AddImage(image, MapRect(ctm, dst), matrix, paint);
+ }
+
+ void onDrawImageNine(const SkImage* image,
+ const SkIRect& center,
+ const SkRect& dst,
+ const SkPaint* paint) override {
+ AddImage(image, dst, this->getTotalMatrix(), paint);
+ }
+
+ private:
+ DiscardableImageSet* image_set_;
+ const SkRect canvas_bounds_;
+
+ void AddImage(const SkImage* image,
+ const SkRect& rect,
+ const SkMatrix& matrix,
+ const SkPaint* paint) {
+ if (rect.intersects(canvas_bounds_) && image->isLazyGenerated()) {
+ SkFilterQuality filter_quality = kNone_SkFilterQuality;
+ if (paint) {
+ filter_quality = paint->getFilterQuality();
+ }
+ image_set_->Add(image, rect, matrix, filter_quality);
+ }
+ }
+};
+
+} // namespace
+
+void DiscardableImageUtils::GatherDiscardableImages(
+ SkPicture* picture,
+ std::vector<PositionImage>* images) {
+ images->clear();
+ DiscardableImageSet image_set(images);
+
+ SkIRect picture_ibounds = picture->cullRect().roundOut();
+ // Use right/bottom as the size so that we don't need a translate and, as a
+ // result, the information is returned relative to the picture's origin.
+ GatherDiscardableImageCanvas canvas(picture_ibounds.right(),
+ picture_ibounds.bottom(), &image_set);
+
+ canvas.drawPicture(picture);
+}
+
+} // namespace skia
diff --git a/skia/ext/discardable_image_utils.h b/skia/ext/discardable_image_utils.h
new file mode 100644
index 0000000..b2d7c93
--- /dev/null
+++ b/skia/ext/discardable_image_utils.h
@@ -0,0 +1,33 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SKIA_EXT_PIXEL_REF_UTILS_H_
+#define SKIA_EXT_PIXEL_REF_UTILS_H_
+
+#include <vector>
+
+#include "SkPicture.h"
+#include "SkRect.h"
+
+namespace skia {
+
+class SK_API DiscardableImageUtils {
+ public:
+ struct PositionImage {
+ const SkImage* image;
+ SkRect image_rect;
+ SkMatrix matrix;
+ SkFilterQuality filter_quality;
+ };
+
+ static void GatherDiscardableImages(SkPicture* picture,
+ std::vector<PositionImage>* images);
+};
+
+using PositionImage = DiscardableImageUtils::PositionImage;
+using DiscardableImageList = std::vector<PositionImage>;
+
+} // namespace skia
+
+#endif
diff --git a/skia/ext/discardable_image_utils_unittest.cc b/skia/ext/discardable_image_utils_unittest.cc
new file mode 100644
index 0000000..0357b61
--- /dev/null
+++ b/skia/ext/discardable_image_utils_unittest.cc
@@ -0,0 +1,185 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/test/geometry_test_utils.h"
+#include "skia/ext/discardable_image_utils.h"
+#include "skia/ext/refptr.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkImageGenerator.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
+#include "third_party/skia/src/core/SkOrderedReadBuffer.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/skia_util.h"
+
+namespace skia {
+
+namespace {
+
+class TestImageGenerator : public SkImageGenerator {
+ public:
+ TestImageGenerator(const SkImageInfo& info) : SkImageGenerator(info) {}
+};
+
+skia::RefPtr<SkImage> CreateDiscardableImage(const gfx::Size& size) {
+ const SkImageInfo info =
+ SkImageInfo::MakeN32Premul(size.width(), size.height());
+ return skia::AdoptRef(
+ SkImage::NewFromGenerator(new TestImageGenerator(info)));
+}
+
+SkCanvas* StartRecording(SkPictureRecorder* recorder, gfx::Rect layer_rect) {
+ SkCanvas* canvas =
+ recorder->beginRecording(layer_rect.width(), layer_rect.height());
+
+ canvas->save();
+ canvas->translate(-layer_rect.x(), -layer_rect.y());
+ canvas->clipRect(SkRect::MakeXYWH(layer_rect.x(), layer_rect.y(),
+ layer_rect.width(), layer_rect.height()));
+
+ return canvas;
+}
+
+SkPicture* StopRecording(SkPictureRecorder* recorder, SkCanvas* canvas) {
+ canvas->restore();
+ return recorder->endRecordingAsPicture();
+}
+
+void VerifyScales(SkScalar x_scale,
+ SkScalar y_scale,
+ const SkMatrix& matrix,
+ int source_line) {
+ SkSize scales;
+ bool success = matrix.decomposeScale(&scales);
+ EXPECT_TRUE(success) << "line: " << source_line;
+ EXPECT_FLOAT_EQ(x_scale, scales.width()) << "line: " << source_line;
+ EXPECT_FLOAT_EQ(y_scale, scales.height()) << "line: " << source_line;
+}
+
+} // namespace
+
+TEST(DiscardableImageUtilsTest, DrawImage) {
+ gfx::Rect layer_rect(0, 0, 256, 256);
+
+ SkPictureRecorder recorder;
+ SkCanvas* canvas = StartRecording(&recorder, layer_rect);
+
+ skia::RefPtr<SkImage> first = CreateDiscardableImage(gfx::Size(50, 50));
+ skia::RefPtr<SkImage> second = CreateDiscardableImage(gfx::Size(50, 50));
+ skia::RefPtr<SkImage> third = CreateDiscardableImage(gfx::Size(50, 50));
+ skia::RefPtr<SkImage> fourth = CreateDiscardableImage(gfx::Size(50, 1));
+ skia::RefPtr<SkImage> fifth = CreateDiscardableImage(gfx::Size(10, 10));
+ skia::RefPtr<SkImage> sixth = CreateDiscardableImage(gfx::Size(10, 10));
+
+ canvas->save();
+
+ // At (0, 0).
+ canvas->drawImage(first.get(), 0, 0);
+ canvas->translate(25, 0);
+ // At (25, 0).
+ canvas->drawImage(second.get(), 0, 0);
+ canvas->translate(0, 50);
+ // At (50, 50).
+ canvas->drawImage(third.get(), 25, 0);
+
+ canvas->restore();
+ canvas->save();
+
+ canvas->translate(1, 0);
+ canvas->rotate(90);
+ // At (1, 0), rotated 90 degrees
+ canvas->drawImage(fourth.get(), 0, 0);
+
+ canvas->restore();
+ canvas->save();
+
+ canvas->scale(5.f, 6.f);
+ // At (0, 0), scaled by 5 and 6
+ canvas->drawImage(fifth.get(), 0, 0);
+
+ canvas->restore();
+
+ canvas->rotate(27);
+ canvas->scale(3.3f, 0.4f);
+
+ canvas->drawImage(sixth.get(), 0, 0);
+
+ canvas->restore();
+
+ skia::RefPtr<SkPicture> picture =
+ skia::AdoptRef(StopRecording(&recorder, canvas));
+
+ std::vector<skia::DiscardableImageUtils::PositionImage> images;
+ skia::DiscardableImageUtils::GatherDiscardableImages(picture.get(), &images);
+
+ EXPECT_EQ(6u, images.size());
+ EXPECT_FLOAT_RECT_EQ(SkRect::MakeXYWH(0, 0, 50, 50), images[0].image_rect);
+ VerifyScales(1.f, 1.f, images[0].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[0].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(25, 0, 50, 50), images[1].image_rect);
+ VerifyScales(1.f, 1.f, images[1].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[1].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(50, 50, 50, 50), images[2].image_rect);
+ VerifyScales(1.f, 1.f, images[2].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[2].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 1, 50), images[3].image_rect);
+ VerifyScales(1.f, 1.f, images[3].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[3].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 50, 60), images[4].image_rect);
+ VerifyScales(5.f, 6.f, images[4].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[4].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(-1.8159621f, 0, 31.219175f, 18.545712f),
+ images[5].image_rect);
+ VerifyScales(3.3f, 0.4f, images[5].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[5].filter_quality);
+}
+
+TEST(DiscardableImageUtilsTest, DrawImageRect) {
+ gfx::Rect layer_rect(0, 0, 256, 256);
+
+ SkPictureRecorder recorder;
+ SkCanvas* canvas = StartRecording(&recorder, layer_rect);
+
+ skia::RefPtr<SkImage> first = CreateDiscardableImage(gfx::Size(50, 50));
+ skia::RefPtr<SkImage> second = CreateDiscardableImage(gfx::Size(50, 50));
+ skia::RefPtr<SkImage> third = CreateDiscardableImage(gfx::Size(50, 50));
+
+ canvas->save();
+
+ SkPaint paint;
+
+ // (0, 0, 100, 100).
+ canvas->drawImageRect(first.get(), SkRect::MakeWH(100, 100), &paint);
+ canvas->translate(25, 0);
+ // (75, 50, 10, 10).
+ canvas->drawImageRect(second.get(), SkRect::MakeXYWH(50, 50, 10, 10), &paint);
+ canvas->translate(5, 50);
+ // (0, 30, 100, 100).
+ canvas->drawImageRect(third.get(), SkRect::MakeXYWH(-30, -20, 100, 100),
+ &paint);
+
+ canvas->restore();
+
+ skia::RefPtr<SkPicture> picture =
+ skia::AdoptRef(StopRecording(&recorder, canvas));
+
+ std::vector<skia::DiscardableImageUtils::PositionImage> images;
+ skia::DiscardableImageUtils::GatherDiscardableImages(picture.get(), &images);
+
+ EXPECT_EQ(3u, images.size());
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 0, 100, 100), images[0].image_rect);
+ VerifyScales(2.f, 2.f, images[0].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[0].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(75, 50, 10, 10), images[1].image_rect);
+ VerifyScales(0.2f, 0.2f, images[1].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[1].filter_quality);
+ EXPECT_FLOAT_RECT_EQ(gfx::RectF(0, 30, 100, 100), images[2].image_rect);
+ VerifyScales(2.f, 2.f, images[2].matrix, __LINE__);
+ EXPECT_EQ(kNone_SkFilterQuality, images[2].filter_quality);
+}
+
+} // namespace skia
diff --git a/skia/skia_chrome.gypi b/skia/skia_chrome.gypi
index 724cb86..9efc631 100644
--- a/skia/skia_chrome.gypi
+++ b/skia/skia_chrome.gypi
@@ -45,6 +45,7 @@
'ext/platform_device_linux.cc',
'ext/platform_device_mac.cc',
'ext/platform_device_win.cc',
+ 'ext/discardable_image_utils.cc',
'ext/recursive_gaussian_convolution.cc',
'ext/SkDiscardableMemory_chrome.cc',
'ext/SkMemory_new_handler.cpp',
diff --git a/skia/skia_tests.gyp b/skia/skia_tests.gyp
index f120d7c..32afbdb 100644
--- a/skia/skia_tests.gyp
+++ b/skia/skia_tests.gyp
@@ -22,6 +22,7 @@
'ext/analysis_canvas_unittest.cc',
'ext/bitmap_platform_device_mac_unittest.cc',
'ext/convolver_unittest.cc',
+ 'ext/discardable_image_utils_unittest.cc',
'ext/image_operations_unittest.cc',
'ext/pixel_ref_utils_unittest.cc',
'ext/platform_canvas_unittest.cc',