OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "skia/ext/pixel_ref_utils.h" | 5 #include "skia/ext/pixel_ref_utils.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "third_party/skia/include/core/SkBitmapDevice.h" | 9 #include "third_party/skia/include/core/SkBitmapDevice.h" |
10 #include "third_party/skia/include/core/SkCanvas.h" | 10 #include "third_party/skia/include/core/SkCanvas.h" |
11 #include "third_party/skia/include/core/SkData.h" | 11 #include "third_party/skia/include/core/SkData.h" |
12 #include "third_party/skia/include/core/SkDraw.h" | 12 #include "third_party/skia/include/core/SkDraw.h" |
13 #include "third_party/skia/include/core/SkPath.h" | 13 #include "third_party/skia/include/core/SkPath.h" |
14 #include "third_party/skia/include/core/SkPixelRef.h" | 14 #include "third_party/skia/include/core/SkPixelRef.h" |
15 #include "third_party/skia/include/core/SkRRect.h" | 15 #include "third_party/skia/include/core/SkRRect.h" |
16 #include "third_party/skia/include/core/SkRect.h" | 16 #include "third_party/skia/include/core/SkRect.h" |
17 #include "third_party/skia/include/core/SkShader.h" | 17 #include "third_party/skia/include/core/SkShader.h" |
18 #include "third_party/skia/include/core/SkTextBlob.h" | 18 #include "third_party/skia/include/core/SkTextBlob.h" |
19 #include "third_party/skia/include/utils/SkNoSaveLayerCanvas.h" | 19 #include "third_party/skia/include/utils/SkNoSaveLayerCanvas.h" |
20 #include "third_party/skia/src/core/SkRasterClip.h" | 20 #include "third_party/skia/src/core/SkRasterClip.h" |
21 | 21 |
22 namespace skia { | 22 namespace skia { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 // URI label for a discardable SkPixelRef. | |
27 const char kLabelDiscardable[] = "discardable"; | |
28 | |
29 class DiscardablePixelRefSet { | 26 class DiscardablePixelRefSet { |
30 public: | 27 public: |
31 DiscardablePixelRefSet( | 28 DiscardablePixelRefSet( |
32 std::vector<PixelRefUtils::PositionPixelRef>* pixel_refs) | 29 std::vector<PixelRefUtils::PositionPixelRef>* pixel_refs) |
33 : pixel_refs_(pixel_refs) {} | 30 : pixel_refs_(pixel_refs) {} |
34 | 31 |
35 void Add(SkPixelRef* pixel_ref, | 32 void Add(SkPixelRef* pixel_ref, |
36 const SkRect& rect, | 33 const SkRect& rect, |
37 const SkMatrix& matrix, | 34 const SkMatrix& matrix, |
38 SkFilterQuality filter_quality) { | 35 SkFilterQuality filter_quality) { |
39 // Only save discardable pixel refs. | 36 // We should only be saving discardable pixel refs. |
40 if (pixel_ref->getURI() && | 37 SkASSERT(pixel_ref); |
41 !strcmp(pixel_ref->getURI(), kLabelDiscardable)) { | 38 SkASSERT(pixel_ref->isLazyGenerated()); |
42 PixelRefUtils::PositionPixelRef position_pixel_ref; | 39 |
43 position_pixel_ref.pixel_ref = pixel_ref; | 40 PixelRefUtils::PositionPixelRef position_pixel_ref; |
44 position_pixel_ref.pixel_ref_rect = rect; | 41 position_pixel_ref.pixel_ref = pixel_ref; |
45 position_pixel_ref.matrix = matrix; | 42 position_pixel_ref.pixel_ref_rect = rect; |
46 position_pixel_ref.filter_quality = filter_quality; | 43 position_pixel_ref.matrix = matrix; |
47 pixel_refs_->push_back(position_pixel_ref); | 44 position_pixel_ref.filter_quality = filter_quality; |
48 } | 45 pixel_refs_->push_back(position_pixel_ref); |
49 } | 46 } |
50 | 47 |
51 private: | 48 private: |
52 std::vector<PixelRefUtils::PositionPixelRef>* pixel_refs_; | 49 std::vector<PixelRefUtils::PositionPixelRef>* pixel_refs_; |
53 }; | 50 }; |
54 | 51 |
55 class GatherPixelRefDevice : public SkBitmapDevice { | 52 class GatherPixelRefDevice : public SkBitmapDevice { |
56 public: | 53 public: |
57 GatherPixelRefDevice(const SkBitmap& bm, | 54 GatherPixelRefDevice(const SkBitmap& bm, |
58 DiscardablePixelRefSet* pixel_ref_set) | 55 DiscardablePixelRefSet* pixel_ref_set) |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 matrix.mapRect(&mapped_rect, bitmap_rect); | 173 matrix.mapRect(&mapped_rect, bitmap_rect); |
177 | 174 |
178 SkMatrix identity; | 175 SkMatrix identity; |
179 identity.setIdentity(); | 176 identity.setIdentity(); |
180 // Sprites aren't affected by current matrix, so use the identity matrix. | 177 // Sprites aren't affected by current matrix, so use the identity matrix. |
181 AddBitmap(bitmap, mapped_rect, identity, paint.getFilterQuality()); | 178 AddBitmap(bitmap, mapped_rect, identity, paint.getFilterQuality()); |
182 SkBitmap paint_bitmap; | 179 SkBitmap paint_bitmap; |
183 if (GetBitmapFromPaint(paint, &paint_bitmap)) | 180 if (GetBitmapFromPaint(paint, &paint_bitmap)) |
184 AddBitmap(paint_bitmap, mapped_rect, identity, paint.getFilterQuality()); | 181 AddBitmap(paint_bitmap, mapped_rect, identity, paint.getFilterQuality()); |
185 } | 182 } |
| 183 void drawImage(const SkDraw& draw, |
| 184 const SkImage* image, |
| 185 SkScalar x, |
| 186 SkScalar y, |
| 187 const SkPaint& paint) override { |
| 188 const SkMatrix image_matrix = SkMatrix::MakeTrans(x, y); |
| 189 DrawImageInternal(draw, image, image_matrix, paint); |
| 190 } |
| 191 void drawImageRect(const SkDraw& draw, |
| 192 const SkImage* image, |
| 193 const SkRect* src_or_null, |
| 194 const SkRect& dst, |
| 195 const SkPaint& paint, |
| 196 SkCanvas::SrcRectConstraint) override { |
| 197 const SkRect src = src_or_null |
| 198 ? *src_or_null |
| 199 : SkRect::MakeIWH(image->width(), image->height()); |
| 200 const SkMatrix image_matrix = |
| 201 SkMatrix::MakeRectToRect(src, dst, SkMatrix::kFill_ScaleToFit); |
| 202 DrawImageInternal(draw, image, image_matrix, paint); |
| 203 } |
186 void drawText(const SkDraw& draw, | 204 void drawText(const SkDraw& draw, |
187 const void* text, | 205 const void* text, |
188 size_t len, | 206 size_t len, |
189 SkScalar x, | 207 SkScalar x, |
190 SkScalar y, | 208 SkScalar y, |
191 const SkPaint& paint) override { | 209 const SkPaint& paint) override { |
192 SkBitmap bitmap; | 210 SkBitmap bitmap; |
193 if (!GetBitmapFromPaint(paint, &bitmap)) | 211 if (!GetBitmapFromPaint(paint, &bitmap)) |
194 return; | 212 return; |
195 | 213 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 return false; | 365 return false; |
348 } | 366 } |
349 | 367 |
350 private: | 368 private: |
351 DiscardablePixelRefSet* pixel_ref_set_; | 369 DiscardablePixelRefSet* pixel_ref_set_; |
352 | 370 |
353 void AddBitmap(const SkBitmap& bm, | 371 void AddBitmap(const SkBitmap& bm, |
354 const SkRect& rect, | 372 const SkRect& rect, |
355 const SkMatrix& matrix, | 373 const SkMatrix& matrix, |
356 SkFilterQuality filter_quality) { | 374 SkFilterQuality filter_quality) { |
357 SkRect canvas_rect = SkRect::MakeWH(width(), height()); | 375 const SkRect canvas_rect = SkRect::Make(imageInfo().bounds()); |
358 if (rect.intersects(canvas_rect)) { | 376 if (rect.intersects(canvas_rect) && bm.pixelRef()->isLazyGenerated()) { |
359 pixel_ref_set_->Add(bm.pixelRef(), rect, matrix, filter_quality); | 377 pixel_ref_set_->Add(bm.pixelRef(), rect, matrix, filter_quality); |
360 } | 378 } |
361 } | 379 } |
362 | 380 |
| 381 void AddImage(const SkImage* image, |
| 382 const SkRect& rect, |
| 383 const SkMatrix& matrix, |
| 384 SkFilterQuality filter_quality) { |
| 385 const SkRect canvas_rect = SkRect::Make(imageInfo().bounds()); |
| 386 if (rect.intersects(canvas_rect) && image->isLazyGenerated()) { |
| 387 SkBitmap bm; |
| 388 if (image->asLegacyBitmap(&bm, SkImage::kRO_LegacyBitmapMode) && bm.pixelR
ef()) { |
| 389 pixel_ref_set_->Add(bm.pixelRef(), rect, matrix, filter_quality); |
| 390 } |
| 391 } |
| 392 } |
| 393 |
363 bool GetBitmapFromPaint(const SkPaint& paint, SkBitmap* bm) { | 394 bool GetBitmapFromPaint(const SkPaint& paint, SkBitmap* bm) { |
364 SkShader* shader = paint.getShader(); | 395 SkShader* shader = paint.getShader(); |
365 if (shader) { | 396 if (shader) { |
366 // Check whether the shader is a gradient in order to prevent generation | 397 // Check whether the shader is a gradient in order to prevent generation |
367 // of bitmaps from gradient shaders, which implement asABitmap. | 398 // of bitmaps from gradient shaders, which implement asABitmap. |
368 if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) | 399 if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) |
369 return shader->asABitmap(bm, NULL, NULL); | 400 return shader->asABitmap(bm, NULL, NULL); |
370 } | 401 } |
371 return false; | 402 return false; |
372 } | 403 } |
| 404 |
| 405 void DrawImageInternal(const SkDraw& draw, |
| 406 const SkImage* image, |
| 407 const SkMatrix& matrix, |
| 408 const SkPaint& paint) { |
| 409 const SkMatrix total_matrix = SkMatrix::Concat(*draw.fMatrix, matrix); |
| 410 const SkRect image_rect = SkRect::MakeIWH(image->width(), image->height())
; |
| 411 SkRect mapped_rect; |
| 412 total_matrix.mapRect(&mapped_rect, image_rect); |
| 413 AddImage(image, mapped_rect, total_matrix, paint.getFilterQuality()); |
| 414 |
| 415 SkBitmap paint_bitmap; |
| 416 if (GetBitmapFromPaint(paint, &paint_bitmap)) { |
| 417 AddBitmap(paint_bitmap, mapped_rect, total_matrix, |
| 418 paint.getFilterQuality()); |
| 419 } |
| 420 } |
373 }; | 421 }; |
374 | 422 |
375 } // namespace | 423 } // namespace |
376 | 424 |
377 void PixelRefUtils::GatherDiscardablePixelRefs( | 425 void PixelRefUtils::GatherDiscardablePixelRefs( |
378 SkPicture* picture, | 426 SkPicture* picture, |
379 std::vector<PositionPixelRef>* pixel_refs) { | 427 std::vector<PositionPixelRef>* pixel_refs) { |
380 pixel_refs->clear(); | 428 pixel_refs->clear(); |
381 DiscardablePixelRefSet pixel_ref_set(pixel_refs); | 429 DiscardablePixelRefSet pixel_ref_set(pixel_refs); |
382 | 430 |
383 SkRect picture_bounds = picture->cullRect(); | 431 SkRect picture_bounds = picture->cullRect(); |
384 SkIRect picture_ibounds = picture_bounds.roundOut(); | 432 SkIRect picture_ibounds = picture_bounds.roundOut(); |
385 SkBitmap empty_bitmap; | 433 SkBitmap empty_bitmap; |
386 // Use right/bottom as the size so that we don't need a translate and, as a | 434 // Use right/bottom as the size so that we don't need a translate and, as a |
387 // result, the information is returned relative to the picture's origin. | 435 // result, the information is returned relative to the picture's origin. |
388 empty_bitmap.setInfo(SkImageInfo::MakeUnknown(picture_ibounds.right(), | 436 empty_bitmap.setInfo(SkImageInfo::MakeUnknown(picture_ibounds.right(), |
389 picture_ibounds.bottom())); | 437 picture_ibounds.bottom())); |
390 | 438 |
391 GatherPixelRefDevice device(empty_bitmap, &pixel_ref_set); | 439 GatherPixelRefDevice device(empty_bitmap, &pixel_ref_set); |
392 SkNoSaveLayerCanvas canvas(&device); | 440 SkNoSaveLayerCanvas canvas(&device); |
393 | 441 |
394 canvas.drawPicture(picture); | 442 canvas.drawPicture(picture); |
395 } | 443 } |
396 | 444 |
397 } // namespace skia | 445 } // namespace skia |
OLD | NEW |