| Index: tests/PictureTest.cpp
|
| ===================================================================
|
| --- tests/PictureTest.cpp (revision 14579)
|
| +++ tests/PictureTest.cpp (working copy)
|
| @@ -6,12 +6,18 @@
|
| */
|
|
|
| #include "SkBitmapDevice.h"
|
| +#if SK_SUPPORT_GPU
|
| +#include "SkBlurImageFilter.h"
|
| +#endif
|
| #include "SkCanvas.h"
|
| #include "SkColorPriv.h"
|
| #include "SkDashPathEffect.h"
|
| #include "SkData.h"
|
| #include "SkDecodingImageGenerator.h"
|
| #include "SkError.h"
|
| +#if SK_SUPPORT_GPU
|
| +#include "SkGpuDevice.h"
|
| +#endif
|
| #include "SkImageEncoder.h"
|
| #include "SkImageGenerator.h"
|
| #include "SkPaint.h"
|
| @@ -22,6 +28,12 @@
|
| #include "SkRandom.h"
|
| #include "SkShader.h"
|
| #include "SkStream.h"
|
| +
|
| +#if SK_SUPPORT_GPU
|
| +#include "SkSurface.h"
|
| +#include "GrContextFactory.h"
|
| +#include "GrPictureUtils.h"
|
| +#endif
|
| #include "Test.h"
|
|
|
| static const int gColorScale = 30;
|
| @@ -765,6 +777,138 @@
|
| // hairline stroked AA concave paths are fine for GPU rendering
|
| REPORTER_ASSERT(reporter, picture->suitableForGpuRasterization(NULL));
|
| }
|
| +
|
| +static void test_gpu_picture_optimization(skiatest::Reporter* reporter,
|
| + GrContextFactory* factory) {
|
| +
|
| + GrContext* context = factory->get(GrContextFactory::kNative_GLContextType);
|
| +
|
| + static const int kWidth = 100;
|
| + static const int kHeight = 100;
|
| +
|
| + SkAutoTUnref<SkPicture> pict;
|
| +
|
| + // create a picture with the structure:
|
| + // 1)
|
| + // SaveLayer
|
| + // Restore
|
| + // 2)
|
| + // SaveLayer
|
| + // Translate
|
| + // SaveLayer w/ bound
|
| + // Restore
|
| + // Restore
|
| + // 3)
|
| + // SaveLayer w/ copyable paint
|
| + // Restore
|
| + // 4)
|
| + // SaveLayer w/ non-copyable paint
|
| + // Restore
|
| + {
|
| + SkPictureRecorder recorder;
|
| +
|
| + SkCanvas* c = recorder.beginRecording(kWidth, kHeight, NULL, 0);
|
| + // 1)
|
| + c->saveLayer(NULL, NULL);
|
| + c->restore();
|
| +
|
| + // 2)
|
| + c->saveLayer(NULL, NULL);
|
| + c->translate(kWidth/2, kHeight/2);
|
| + SkRect r = SkRect::MakeXYWH(0, 0, kWidth/2, kHeight/2);
|
| + c->saveLayer(&r, NULL);
|
| + c->restore();
|
| + c->restore();
|
| +
|
| + // 3)
|
| + {
|
| + SkPaint p;
|
| + p.setColor(SK_ColorRED);
|
| + c->saveLayer(NULL, &p);
|
| + c->restore();
|
| + }
|
| + // 4)
|
| + // TODO: this case will need to be removed once the paint's are immutable
|
| + {
|
| + SkPaint p;
|
| + SkBitmap bmp;
|
| + bmp.allocN32Pixels(10, 10);
|
| + bmp.eraseColor(SK_ColorGREEN);
|
| + bmp.setAlphaType(kOpaque_SkAlphaType);
|
| + SkShader* shader = SkShader::CreateBitmapShader(bmp,
|
| + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
|
| + p.setShader(shader)->unref();
|
| +
|
| + c->saveLayer(NULL, &p);
|
| + c->restore();
|
| + }
|
| +
|
| + pict.reset(recorder.endRecording());
|
| + }
|
| +
|
| + // Now test out the SaveLayer extraction
|
| + {
|
| + SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
|
| +
|
| + SkAutoTUnref<SkSurface> surface(SkSurface::NewScratchRenderTarget(context, info));
|
| +
|
| + SkCanvas* canvas = surface->getCanvas();
|
| +
|
| + canvas->EXPERIMENTAL_optimize(pict);
|
| +
|
| + SkPicture::AccelData::Key key = GPUAccelData::ComputeAccelDataKey();
|
| +
|
| + const SkPicture::AccelData* data = pict->EXPERIMENTAL_getAccelData(key);
|
| + REPORTER_ASSERT(reporter, NULL != data);
|
| +
|
| + const GPUAccelData *gpuData = static_cast<const GPUAccelData*>(data);
|
| + REPORTER_ASSERT(reporter, 5 == gpuData->numSaveLayers());
|
| +
|
| + const GPUAccelData::SaveLayerInfo& info0 = gpuData->saveLayerInfo(0);
|
| + // The parent/child layer appear in reverse order
|
| + const GPUAccelData::SaveLayerInfo& info1 = gpuData->saveLayerInfo(2);
|
| + const GPUAccelData::SaveLayerInfo& info2 = gpuData->saveLayerInfo(1);
|
| + const GPUAccelData::SaveLayerInfo& info3 = gpuData->saveLayerInfo(3);
|
| + const GPUAccelData::SaveLayerInfo& info4 = gpuData->saveLayerInfo(4);
|
| +
|
| + REPORTER_ASSERT(reporter, info0.fValid);
|
| + REPORTER_ASSERT(reporter, kWidth == info0.fSize.fWidth && kHeight == info0.fSize.fHeight);
|
| + REPORTER_ASSERT(reporter, info0.fCTM.isIdentity());
|
| + REPORTER_ASSERT(reporter, 0 == info0.fOffset.fX && 0 == info0.fOffset.fY);
|
| + REPORTER_ASSERT(reporter, NULL != info0.fPaint);
|
| + REPORTER_ASSERT(reporter, !info0.fIsNested && !info0.fHasNestedLayers);
|
| +
|
| + REPORTER_ASSERT(reporter, info1.fValid);
|
| + REPORTER_ASSERT(reporter, kWidth == info1.fSize.fWidth && kHeight == info1.fSize.fHeight);
|
| + REPORTER_ASSERT(reporter, info1.fCTM.isIdentity());
|
| + REPORTER_ASSERT(reporter, 0 == info1.fOffset.fX && 0 == info1.fOffset.fY);
|
| + REPORTER_ASSERT(reporter, NULL != info1.fPaint);
|
| + REPORTER_ASSERT(reporter, !info1.fIsNested && info1.fHasNestedLayers); // has a nested SL
|
| +
|
| + REPORTER_ASSERT(reporter, info2.fValid);
|
| + REPORTER_ASSERT(reporter, kWidth/2 == info2.fSize.fWidth &&
|
| + kHeight/2 == info2.fSize.fHeight); // bound reduces size
|
| + REPORTER_ASSERT(reporter, info2.fCTM.isIdentity()); // translated
|
| + REPORTER_ASSERT(reporter, 0 == info2.fOffset.fX && 0 == info2.fOffset.fY);
|
| + REPORTER_ASSERT(reporter, NULL != info1.fPaint);
|
| + REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); // is nested
|
| +
|
| + REPORTER_ASSERT(reporter, info3.fValid);
|
| + REPORTER_ASSERT(reporter, kWidth == info3.fSize.fWidth && kHeight == info3.fSize.fHeight);
|
| + REPORTER_ASSERT(reporter, info3.fCTM.isIdentity());
|
| + REPORTER_ASSERT(reporter, 0 == info3.fOffset.fX && 0 == info3.fOffset.fY);
|
| + REPORTER_ASSERT(reporter, NULL != info3.fPaint);
|
| + REPORTER_ASSERT(reporter, !info3.fIsNested && !info3.fHasNestedLayers);
|
| +
|
| + REPORTER_ASSERT(reporter, !info4.fValid); // paint is/was uncopyable
|
| + REPORTER_ASSERT(reporter, kWidth == info4.fSize.fWidth && kHeight == info4.fSize.fHeight);
|
| + REPORTER_ASSERT(reporter, 0 == info4.fOffset.fX && 0 == info4.fOffset.fY);
|
| + REPORTER_ASSERT(reporter, info4.fCTM.isIdentity());
|
| + REPORTER_ASSERT(reporter, NULL == info4.fPaint); // paint is/was uncopyable
|
| + REPORTER_ASSERT(reporter, !info4.fIsNested && !info4.fHasNestedLayers);
|
| + }
|
| +}
|
| +
|
| #endif
|
|
|
| static void set_canvas_to_save_count_4(SkCanvas* canvas) {
|
| @@ -1284,6 +1428,12 @@
|
| test_gen_id(reporter);
|
| }
|
|
|
| +#if SK_SUPPORT_GPU
|
| +DEF_GPUTEST(GPUPicture, reporter, factory) {
|
| + test_gpu_picture_optimization(reporter, factory);
|
| +}
|
| +#endif
|
| +
|
| static void draw_bitmaps(const SkBitmap bitmap, SkCanvas* canvas) {
|
| const SkPaint paint;
|
| const SkRect rect = { 5.0f, 5.0f, 8.0f, 8.0f };
|
|
|