1cef04f818820e59fb534eb226f967f72497845d3piotaixr/*
2cef04f818820e59fb534eb226f967f72497845d3piotaixr * Copyright 2014 Google Inc.
3cef04f818820e59fb534eb226f967f72497845d3piotaixr *
4cef04f818820e59fb534eb226f967f72497845d3piotaixr * Use of this source code is governed by a BSD-style license that can be
5cef04f818820e59fb534eb226f967f72497845d3piotaixr * found in the LICENSE file.
6cef04f818820e59fb534eb226f967f72497845d3piotaixr */
7cef04f818820e59fb534eb226f967f72497845d3piotaixr
8cef04f818820e59fb534eb226f967f72497845d3piotaixr#include "SkCanvas.h"
9cef04f818820e59fb534eb226f967f72497845d3piotaixr#include "SkImage.h"
10cef04f818820e59fb534eb226f967f72497845d3piotaixr#include "SkShader.h"
11cef04f818820e59fb534eb226f967f72497845d3piotaixr#include "SkSurface.h"
121530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#include "SkTypes.h"
13cef04f818820e59fb534eb226f967f72497845d3piotaixr#include "Test.h"
14cef04f818820e59fb534eb226f967f72497845d3piotaixr
151530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#if SK_SUPPORT_GPU
161530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#include "GrContext.h"
171530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#endif
181530283c483cb88aa725bce50a6d193dd00ee570kkinnunen
1967c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillipsstatic void test_bitmap_equality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) {
20f0ffb8943b7be477b769db23660a80013f3332ebMike Reed    REPORTER_ASSERT(reporter, bm1.computeByteSize() == bm2.computeByteSize());
21f0ffb8943b7be477b769db23660a80013f3332ebMike Reed    REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.computeByteSize()));
2276d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr}
2376d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
2467c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillipsstatic void paint_source(SkSurface* sourceSurface) {
2576d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkCanvas* sourceCanvas = sourceSurface->getCanvas();
2676d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    sourceCanvas->clear(0xFFDEDEDE);
2776d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
2876d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkPaint paintColor;
2976d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    paintColor.setColor(0xFFFF0000);
3076d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    paintColor.setStyle(SkPaint::kFill_Style);
31cef04f818820e59fb534eb226f967f72497845d3piotaixr
3276d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkRect rect = SkRect::MakeXYWH(
3376d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            SkIntToScalar(1),
3476d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            SkIntToScalar(0),
3576d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            SkIntToScalar(1),
3676d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            SkIntToScalar(sourceSurface->height()));
3776d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
3876d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    sourceCanvas->drawRect(rect, paintColor);
39cef04f818820e59fb534eb226f967f72497845d3piotaixr}
40cef04f818820e59fb534eb226f967f72497845d3piotaixr
4167c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillipsstatic void run_shader_test(skiatest::Reporter* reporter, SkSurface* sourceSurface,
4267c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips                            SkSurface* destinationSurface, SkImageInfo& info) {
4367c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    paint_source(sourceSurface);
44cef04f818820e59fb534eb226f967f72497845d3piotaixr
459ce9d6772df650ceb0511f275e1a83dffa78ff72reed    sk_sp<SkImage> sourceImage(sourceSurface->makeImageSnapshot());
465671c5b9124f17d33bc14b6d347cdc6fe5d19dc8reed    sk_sp<SkShader> sourceShader = sourceImage->makeShader(
47cef04f818820e59fb534eb226f967f72497845d3piotaixr            SkShader::kRepeat_TileMode,
485671c5b9124f17d33bc14b6d347cdc6fe5d19dc8reed            SkShader::kRepeat_TileMode);
49cef04f818820e59fb534eb226f967f72497845d3piotaixr
50cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkPaint paint;
5176d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    paint.setShader(sourceShader);
5276d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
5376d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkCanvas* destinationCanvas = destinationSurface->getCanvas();
5476d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    destinationCanvas->clear(SK_ColorTRANSPARENT);
5576d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    destinationCanvas->drawPaint(paint);
56cef04f818820e59fb534eb226f967f72497845d3piotaixr
57cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkBitmap bmOrig;
5812e946b4bfdf598bffb276776ea6e25439e25265Mike Reed    bmOrig.allocN32Pixels(info.width(), info.height());
59f19421961c59ceabfb88a5c5cdf7c7e31a95b015Mike Reed    sourceSurface->readPixels(bmOrig, 0, 0);
6076d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
61cef04f818820e59fb534eb226f967f72497845d3piotaixr
62cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkBitmap bm;
6312e946b4bfdf598bffb276776ea6e25439e25265Mike Reed    bm.allocN32Pixels(info.width(), info.height());
64f19421961c59ceabfb88a5c5cdf7c7e31a95b015Mike Reed    destinationSurface->readPixels(bm, 0, 0);
65cef04f818820e59fb534eb226f967f72497845d3piotaixr
6667c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    test_bitmap_equality(reporter, bmOrig, bm);
6776d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
6876d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    // Test with a translated shader
6976d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkMatrix matrix;
7076d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    matrix.setTranslate(SkIntToScalar(-1), SkIntToScalar(0));
7176d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
725671c5b9124f17d33bc14b6d347cdc6fe5d19dc8reed    sk_sp<SkShader> sourceShaderTranslated = sourceImage->makeShader(
7376d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            SkShader::kRepeat_TileMode,
7476d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            SkShader::kRepeat_TileMode,
755671c5b9124f17d33bc14b6d347cdc6fe5d19dc8reed            &matrix);
7676d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
7776d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    destinationCanvas->clear(SK_ColorTRANSPARENT);
7876d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
7976d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkPaint paintTranslated;
8076d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    paintTranslated.setShader(sourceShaderTranslated);
8176d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
8276d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    destinationCanvas->drawPaint(paintTranslated);
8376d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
8476d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    SkBitmap bmt;
8512e946b4bfdf598bffb276776ea6e25439e25265Mike Reed    bmt.allocN32Pixels(info.width(), info.height());
86f19421961c59ceabfb88a5c5cdf7c7e31a95b015Mike Reed    destinationSurface->readPixels(bmt, 0, 0);
8776d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
8876d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    //  Test correctness
8976d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    {
9076d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr        for (int y = 0; y < info.height(); y++) {
9176d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            REPORTER_ASSERT(reporter, 0xFFFF0000 == bmt.getColor(0, y));
9276d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr
9376d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            for (int x = 1; x < info.width(); x++) {
9476d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr                REPORTER_ASSERT(reporter, 0xFFDEDEDE == bmt.getColor(x, y));
9576d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr            }
9676d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr        }
9776d5b477c92ef076374fc7ea9d551c798656bebdpiotaixr    }
98cef04f818820e59fb534eb226f967f72497845d3piotaixr}
99cef04f818820e59fb534eb226f967f72497845d3piotaixr
100cef04f818820e59fb534eb226f967f72497845d3piotaixrDEF_TEST(ImageNewShader, reporter) {
101cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
102cef04f818820e59fb534eb226f967f72497845d3piotaixr
103e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto sourceSurface(SkSurface::MakeRaster(info));
104e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto destinationSurface(SkSurface::MakeRaster(info));
105cef04f818820e59fb534eb226f967f72497845d3piotaixr
10667c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
107cef04f818820e59fb534eb226f967f72497845d3piotaixr}
108cef04f818820e59fb534eb226f967f72497845d3piotaixr
109cef04f818820e59fb534eb226f967f72497845d3piotaixr#if SK_SUPPORT_GPU
110cef04f818820e59fb534eb226f967f72497845d3piotaixr
11167c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillipsstatic void gpu_to_gpu(skiatest::Reporter* reporter, GrContext* context) {
112cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
113cef04f818820e59fb534eb226f967f72497845d3piotaixr
114e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto sourceSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
115e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto destinationSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
116cef04f818820e59fb534eb226f967f72497845d3piotaixr
11767c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
118cef04f818820e59fb534eb226f967f72497845d3piotaixr}
119cef04f818820e59fb534eb226f967f72497845d3piotaixr
12067c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillipsstatic void gpu_to_raster(skiatest::Reporter* reporter, GrContext* context) {
121cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
122cef04f818820e59fb534eb226f967f72497845d3piotaixr
123e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto sourceSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
124e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto destinationSurface(SkSurface::MakeRaster(info));
125cef04f818820e59fb534eb226f967f72497845d3piotaixr
12667c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
127cef04f818820e59fb534eb226f967f72497845d3piotaixr}
128cef04f818820e59fb534eb226f967f72497845d3piotaixr
12967c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillipsstatic void raster_to_gpu(skiatest::Reporter* reporter, GrContext* context) {
130cef04f818820e59fb534eb226f967f72497845d3piotaixr    SkImageInfo info = SkImageInfo::MakeN32Premul(5, 5);
131cef04f818820e59fb534eb226f967f72497845d3piotaixr
132e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto sourceSurface(SkSurface::MakeRaster(info));
133e8f3062a36d3682f4019309a32b5b84dc9eddf8creed    auto destinationSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
134cef04f818820e59fb534eb226f967f72497845d3piotaixr
13567c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    run_shader_test(reporter, sourceSurface.get(), destinationSurface.get(), info);
136cef04f818820e59fb534eb226f967f72497845d3piotaixr}
137cef04f818820e59fb534eb226f967f72497845d3piotaixr
13868d9134bec16e91c4a6cde071bcaa579bc0801a7bsalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageNewShader_GPU, reporter, ctxInfo) {
1391530283c483cb88aa725bce50a6d193dd00ee570kkinnunen    //  GPU -> GPU
14067c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    gpu_to_gpu(reporter, ctxInfo.grContext());
141cef04f818820e59fb534eb226f967f72497845d3piotaixr
1421530283c483cb88aa725bce50a6d193dd00ee570kkinnunen    //  GPU -> RASTER
14367c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    gpu_to_raster(reporter, ctxInfo.grContext());
144cef04f818820e59fb534eb226f967f72497845d3piotaixr
1451530283c483cb88aa725bce50a6d193dd00ee570kkinnunen    //  RASTER -> GPU
14667c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips    raster_to_gpu(reporter, ctxInfo.grContext());
147cef04f818820e59fb534eb226f967f72497845d3piotaixr}
148cef04f818820e59fb534eb226f967f72497845d3piotaixr
149cef04f818820e59fb534eb226f967f72497845d3piotaixr#endif
150