OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
| 8 #include "SkBigPicture.h" |
8 #include "SkBBoxHierarchy.h" | 9 #include "SkBBoxHierarchy.h" |
9 #include "SkBlurImageFilter.h" | 10 #include "SkBlurImageFilter.h" |
10 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
11 #include "SkColorMatrixFilter.h" | 12 #include "SkColorMatrixFilter.h" |
12 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
13 #include "SkDashPathEffect.h" | 14 #include "SkDashPathEffect.h" |
14 #include "SkData.h" | 15 #include "SkData.h" |
15 #include "SkImageGenerator.h" | 16 #include "SkImageGenerator.h" |
16 #include "SkError.h" | 17 #include "SkError.h" |
17 #include "SkImageEncoder.h" | 18 #include "SkImageEncoder.h" |
18 #include "SkImageGenerator.h" | 19 #include "SkImageGenerator.h" |
19 #include "SkLayerInfo.h" | |
20 #include "SkMD5.h" | 20 #include "SkMD5.h" |
21 #include "SkPaint.h" | 21 #include "SkPaint.h" |
22 #include "SkPicture.h" | 22 #include "SkPicture.h" |
23 #include "SkPictureAnalyzer.h" | 23 #include "SkPictureAnalyzer.h" |
24 #include "SkPictureRecorder.h" | 24 #include "SkPictureRecorder.h" |
25 #include "SkPictureUtils.h" | 25 #include "SkPictureUtils.h" |
26 #include "SkPixelRef.h" | 26 #include "SkPixelRef.h" |
27 #include "SkPixelSerializer.h" | 27 #include "SkPixelSerializer.h" |
28 #include "SkMiniRecorder.h" | 28 #include "SkMiniRecorder.h" |
29 #include "SkRRect.h" | 29 #include "SkRRect.h" |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 canvas = recorder.beginRecording(100, 100); | 312 canvas = recorder.beginRecording(100, 100); |
313 { | 313 { |
314 canvas->drawPicture(picture); | 314 canvas->drawPicture(picture); |
315 } | 315 } |
316 picture = recorder.finishRecordingAsPicture(); | 316 picture = recorder.finishRecordingAsPicture(); |
317 REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRaste
rization()); | 317 REPORTER_ASSERT(reporter, !SkPictureGpuAnalyzer(picture).suitableForGpuRaste
rization()); |
318 } | 318 } |
319 | 319 |
320 #endif // SK_SUPPORT_GPU | 320 #endif // SK_SUPPORT_GPU |
321 | 321 |
322 static void test_savelayer_extraction(skiatest::Reporter* reporter) { | |
323 static const int kWidth = 100; | |
324 static const int kHeight = 100; | |
325 | |
326 // Create complex paint that the bounding box computation code can't | |
327 // optimize away | |
328 SkScalar blueToRedMatrix[20] = { 0 }; | |
329 blueToRedMatrix[2] = blueToRedMatrix[18] = SK_Scalar1; | |
330 sk_sp<SkColorFilter> blueToRed(SkColorFilter::MakeMatrixFilterRowMajor255(bl
ueToRedMatrix)); | |
331 sk_sp<SkImageFilter> filter(SkColorFilterImageFilter::Make(std::move(blueToR
ed), nullptr)); | |
332 | |
333 SkPaint complexPaint; | |
334 complexPaint.setImageFilter(std::move(filter)); | |
335 | |
336 sk_sp<SkPicture> pict, child; | |
337 SkRTreeFactory bbhFactory; | |
338 | |
339 { | |
340 SkPictureRecorder recorder; | |
341 | |
342 SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScal
ar(kHeight), | |
343 &bbhFactory, | |
344 SkPictureRecorder::kComputeSaveLay
erInfo_RecordFlag); | |
345 | |
346 c->saveLayer(nullptr, &complexPaint); | |
347 c->restore(); | |
348 | |
349 child = recorder.finishRecordingAsPicture(); | |
350 } | |
351 | |
352 // create a picture with the structure: | |
353 // 1) | |
354 // SaveLayer | |
355 // Restore | |
356 // 2) | |
357 // SaveLayer | |
358 // Translate | |
359 // SaveLayer w/ bound | |
360 // Restore | |
361 // Restore | |
362 // 3) | |
363 // SaveLayer w/ copyable paint | |
364 // Restore | |
365 // 4) | |
366 // SaveLayer | |
367 // DrawPicture (which has a SaveLayer/Restore pair) | |
368 // Restore | |
369 // 5) | |
370 // SaveLayer | |
371 // DrawPicture with Matrix & Paint (with SaveLayer/Restore pair) | |
372 // Restore | |
373 { | |
374 SkPictureRecorder recorder; | |
375 | |
376 SkCanvas* c = recorder.beginRecording(SkIntToScalar(kWidth), | |
377 SkIntToScalar(kHeight), | |
378 &bbhFactory, | |
379 SkPictureRecorder::kComputeSaveLay
erInfo_RecordFlag); | |
380 // 1) | |
381 c->saveLayer(nullptr, &complexPaint); // layer #0 | |
382 c->restore(); | |
383 | |
384 // 2) | |
385 c->saveLayer(nullptr, nullptr); // layer #1 | |
386 c->translate(kWidth / 2.0f, kHeight / 2.0f); | |
387 SkRect r = SkRect::MakeXYWH(0, 0, kWidth/2, kHeight/2); | |
388 c->saveLayer(&r, &complexPaint); // layer #2 | |
389 c->restore(); | |
390 c->restore(); | |
391 | |
392 // 3) | |
393 { | |
394 c->saveLayer(nullptr, &complexPaint); // layer #3 | |
395 c->restore(); | |
396 } | |
397 | |
398 SkPaint layerPaint; | |
399 layerPaint.setColor(SK_ColorRED); // Non-alpha only to avoid SaveLayerD
rawRestoreNooper | |
400 // 4) | |
401 { | |
402 c->saveLayer(nullptr, &layerPaint); // layer #4 | |
403 c->drawPicture(child); // layer #5 inside picture | |
404 c->restore(); | |
405 } | |
406 // 5 | |
407 { | |
408 SkPaint picturePaint; | |
409 SkMatrix trans; | |
410 trans.setTranslate(10, 10); | |
411 | |
412 c->saveLayer(nullptr, &layerPaint); // layer #6 | |
413 c->drawPicture(child, &trans, &picturePaint); // layer #7 inside
picture | |
414 c->restore(); | |
415 } | |
416 | |
417 pict = recorder.finishRecordingAsPicture(); | |
418 } | |
419 | |
420 // Now test out the SaveLayer extraction | |
421 if (!SkCanvas::Internal_Private_GetIgnoreSaveLayerBounds()) { | |
422 const SkBigPicture* bp = pict->asSkBigPicture(); | |
423 REPORTER_ASSERT(reporter, bp); | |
424 | |
425 const SkBigPicture::AccelData* data = bp->accelData(); | |
426 REPORTER_ASSERT(reporter, data); | |
427 | |
428 const SkLayerInfo *gpuData = static_cast<const SkLayerInfo*>(data); | |
429 REPORTER_ASSERT(reporter, 8 == gpuData->numBlocks()); | |
430 | |
431 const SkLayerInfo::BlockInfo& info0 = gpuData->block(0); | |
432 // The parent/child layers appear in reverse order | |
433 const SkLayerInfo::BlockInfo& info1 = gpuData->block(2); | |
434 const SkLayerInfo::BlockInfo& info2 = gpuData->block(1); | |
435 | |
436 const SkLayerInfo::BlockInfo& info3 = gpuData->block(3); | |
437 | |
438 // The parent/child layers appear in reverse order | |
439 const SkLayerInfo::BlockInfo& info4 = gpuData->block(5); | |
440 const SkLayerInfo::BlockInfo& info5 = gpuData->block(4); | |
441 | |
442 // The parent/child layers appear in reverse order | |
443 const SkLayerInfo::BlockInfo& info6 = gpuData->block(7); | |
444 const SkLayerInfo::BlockInfo& info7 = gpuData->block(6); | |
445 | |
446 REPORTER_ASSERT(reporter, nullptr == info0.fPicture); | |
447 REPORTER_ASSERT(reporter, kWidth == info0.fBounds.width() && | |
448 kHeight == info0.fBounds.height()); | |
449 REPORTER_ASSERT(reporter, info0.fLocalMat.isIdentity()); | |
450 REPORTER_ASSERT(reporter, info0.fPreMat.isIdentity()); | |
451 REPORTER_ASSERT(reporter, 0 == info0.fBounds.fLeft && 0 == info0.fBounds
.fTop); | |
452 REPORTER_ASSERT(reporter, nullptr != info0.fPaint); | |
453 REPORTER_ASSERT(reporter, !info0.fIsNested && !info0.fHasNestedLayers); | |
454 | |
455 REPORTER_ASSERT(reporter, nullptr == info1.fPicture); | |
456 REPORTER_ASSERT(reporter, kWidth/2.0 == info1.fBounds.width() && | |
457 kHeight/2.0 == info1.fBounds.height()); | |
458 REPORTER_ASSERT(reporter, info1.fLocalMat.isIdentity()); | |
459 REPORTER_ASSERT(reporter, info1.fPreMat.isIdentity()); | |
460 REPORTER_ASSERT(reporter, kWidth/2.0 == info1.fBounds.fLeft && | |
461 kHeight/2.0 == info1.fBounds.fTop); | |
462 REPORTER_ASSERT(reporter, nullptr == info1.fPaint); | |
463 REPORTER_ASSERT(reporter, !info1.fIsNested && | |
464 info1.fHasNestedLayers); // has a nested SL | |
465 | |
466 REPORTER_ASSERT(reporter, nullptr == info2.fPicture); | |
467 REPORTER_ASSERT(reporter, kWidth / 2 == info2.fBounds.width() && | |
468 kHeight / 2 == info2.fBounds.height()); // bou
nd reduces size | |
469 REPORTER_ASSERT(reporter, !info2.fLocalMat.isIdentity()); | |
470 REPORTER_ASSERT(reporter, info2.fPreMat.isIdentity()); | |
471 REPORTER_ASSERT(reporter, kWidth / 2 == info2.fBounds.fLeft && // tran
slated | |
472 kHeight / 2 == info2.fBounds.fTop); | |
473 REPORTER_ASSERT(reporter, nullptr != info2.fPaint); | |
474 REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); /
/ is nested | |
475 | |
476 REPORTER_ASSERT(reporter, nullptr == info3.fPicture); | |
477 REPORTER_ASSERT(reporter, kWidth == info3.fBounds.width() && | |
478 kHeight == info3.fBounds.height()); | |
479 REPORTER_ASSERT(reporter, info3.fLocalMat.isIdentity()); | |
480 REPORTER_ASSERT(reporter, info3.fPreMat.isIdentity()); | |
481 REPORTER_ASSERT(reporter, 0 == info3.fBounds.fLeft && 0 == info3.fBounds
.fTop); | |
482 REPORTER_ASSERT(reporter, info3.fPaint); | |
483 REPORTER_ASSERT(reporter, !info3.fIsNested && !info3.fHasNestedLayers); | |
484 | |
485 REPORTER_ASSERT(reporter, nullptr == info4.fPicture); | |
486 REPORTER_ASSERT(reporter, kWidth == info4.fBounds.width() && | |
487 kHeight == info4.fBounds.height()); | |
488 REPORTER_ASSERT(reporter, 0 == info4.fBounds.fLeft && 0 == info4.fBounds
.fTop); | |
489 REPORTER_ASSERT(reporter, info4.fLocalMat.isIdentity()); | |
490 REPORTER_ASSERT(reporter, info4.fPreMat.isIdentity()); | |
491 REPORTER_ASSERT(reporter, info4.fPaint); | |
492 REPORTER_ASSERT(reporter, !info4.fIsNested && | |
493 info4.fHasNestedLayers); // has a nested SL | |
494 | |
495 REPORTER_ASSERT(reporter, child.get() == info5.fPicture); // in a child
picture | |
496 REPORTER_ASSERT(reporter, kWidth == info5.fBounds.width() && | |
497 kHeight == info5.fBounds.height()); | |
498 REPORTER_ASSERT(reporter, 0 == info5.fBounds.fLeft && 0 == info5.fBounds
.fTop); | |
499 REPORTER_ASSERT(reporter, info5.fLocalMat.isIdentity()); | |
500 REPORTER_ASSERT(reporter, info5.fPreMat.isIdentity()); | |
501 REPORTER_ASSERT(reporter, nullptr != info5.fPaint); | |
502 REPORTER_ASSERT(reporter, info5.fIsNested && !info5.fHasNestedLayers); /
/ is nested | |
503 | |
504 REPORTER_ASSERT(reporter, nullptr == info6.fPicture); | |
505 REPORTER_ASSERT(reporter, kWidth-10 == info6.fBounds.width() && | |
506 kHeight-10 == info6.fBounds.height()); | |
507 REPORTER_ASSERT(reporter, 10 == info6.fBounds.fLeft && 10 == info6.fBoun
ds.fTop); | |
508 REPORTER_ASSERT(reporter, info6.fLocalMat.isIdentity()); | |
509 REPORTER_ASSERT(reporter, info6.fPreMat.isIdentity()); | |
510 REPORTER_ASSERT(reporter, info6.fPaint); | |
511 REPORTER_ASSERT(reporter, !info6.fIsNested && | |
512 info6.fHasNestedLayers); // has a nested SL | |
513 | |
514 REPORTER_ASSERT(reporter, child.get() == info7.fPicture); // in a child
picture | |
515 REPORTER_ASSERT(reporter, kWidth == info7.fBounds.width() && | |
516 kHeight == info7.fBounds.height()); | |
517 REPORTER_ASSERT(reporter, 0 == info7.fBounds.fLeft && 0 == info7.fBounds
.fTop); | |
518 REPORTER_ASSERT(reporter, info7.fLocalMat.isIdentity()); | |
519 REPORTER_ASSERT(reporter, info7.fPreMat.isIdentity()); | |
520 REPORTER_ASSERT(reporter, nullptr != info7.fPaint); | |
521 REPORTER_ASSERT(reporter, info7.fIsNested && !info7.fHasNestedLayers); /
/ is nested | |
522 } | |
523 } | |
524 | |
525 static void set_canvas_to_save_count_4(SkCanvas* canvas) { | 322 static void set_canvas_to_save_count_4(SkCanvas* canvas) { |
526 canvas->restoreToCount(1); | 323 canvas->restoreToCount(1); |
527 canvas->save(); | 324 canvas->save(); |
528 canvas->save(); | 325 canvas->save(); |
529 canvas->save(); | 326 canvas->save(); |
530 } | 327 } |
531 | 328 |
532 /** | 329 /** |
533 * A canvas that records the number of saves, saveLayers and restores. | 330 * A canvas that records the number of saves, saveLayers and restores. |
534 */ | 331 */ |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 test_peephole(); | 980 test_peephole(); |
1184 #if SK_SUPPORT_GPU | 981 #if SK_SUPPORT_GPU |
1185 test_gpu_veto(reporter); | 982 test_gpu_veto(reporter); |
1186 #endif | 983 #endif |
1187 test_images_are_found_by_willPlayBackBitmaps(reporter); | 984 test_images_are_found_by_willPlayBackBitmaps(reporter); |
1188 test_analysis(reporter); | 985 test_analysis(reporter); |
1189 test_clip_bound_opt(reporter); | 986 test_clip_bound_opt(reporter); |
1190 test_clip_expansion(reporter); | 987 test_clip_expansion(reporter); |
1191 test_hierarchical(reporter); | 988 test_hierarchical(reporter); |
1192 test_gen_id(reporter); | 989 test_gen_id(reporter); |
1193 test_savelayer_extraction(reporter); | |
1194 test_cull_rect_reset(reporter); | 990 test_cull_rect_reset(reporter); |
1195 } | 991 } |
1196 | 992 |
1197 static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) { | 993 static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) { |
1198 const SkPaint paint; | 994 const SkPaint paint; |
1199 const SkRect rect = { 5.0f, 5.0f, 8.0f, 8.0f }; | 995 const SkRect rect = { 5.0f, 5.0f, 8.0f, 8.0f }; |
1200 const SkIRect irect = { 2, 2, 3, 3 }; | 996 const SkIRect irect = { 2, 2, 3, 3 }; |
1201 | 997 |
1202 // Don't care what these record, as long as they're legal. | 998 // Don't care what these record, as long as they're legal. |
1203 canvas->drawBitmap(bitmap, 0.0f, 0.0f, &paint); | 999 canvas->drawBitmap(bitmap, 0.0f, 0.0f, &paint); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1500 } | 1296 } |
1501 { | 1297 { |
1502 SkPictureRecorder rec; | 1298 SkPictureRecorder rec; |
1503 proc(rec.beginRecording(cull)); | 1299 proc(rec.beginRecording(cull)); |
1504 sk_sp<SkDrawable> dr = rec.finishRecordingAsDrawable( | 1300 sk_sp<SkDrawable> dr = rec.finishRecordingAsDrawable( |
1505 SkPictureRecorder::kReturnNullF
orEmpty_FinishFlag); | 1301 SkPictureRecorder::kReturnNullF
orEmpty_FinishFlag); |
1506 REPORTER_ASSERT(r, !dr.get()); | 1302 REPORTER_ASSERT(r, !dr.get()); |
1507 } | 1303 } |
1508 } | 1304 } |
1509 } | 1305 } |
OLD | NEW |