1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "tests/common/TestUtils.h"
18 
19 #include <hwui/Paint.h>
20 #include <SkAlphaType.h>
21 #include <SkBitmap.h>
22 #include <SkBlendMode.h>
23 #include <SkCanvas.h>
24 #include <SkCanvasStateUtils.h>
25 #include <SkColor.h>
26 #include <SkColorSpace.h>
27 #include <SkColorType.h>
28 #include <SkImageInfo.h>
29 #include <SkPicture.h>
30 #include <SkPictureRecorder.h>
31 #include <SkRefCnt.h>
32 #include <SkSurface.h>
33 #include <gtest/gtest.h>
34 
35 using namespace android;
36 using namespace android::uirenderer;
37 
TEST(SkiaCanvas,drawShadowLayer)38 TEST(SkiaCanvas, drawShadowLayer) {
39     auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(10, 10));
40     SkiaCanvas canvas(surface->getCanvas());
41 
42     // clear to white
43     canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrc);
44 
45     Paint paint;
46     // it is transparent to ensure that we still draw the rect since it has a looper
47     paint.setColor(SK_ColorTRANSPARENT);
48     // this is how view's shadow layers are implemented
49     paint.setLooper(BlurDrawLooper::Make({0, 0, 0, 240.0f / 255}, nullptr, 6.0f, {0, 10}));
50     canvas.drawRect(3, 3, 7, 7, paint);
51 
52     ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE);
53     ASSERT_NE(TestUtils::getColor(surface, 5, 5), SK_ColorWHITE);
54 }
55 
TEST(SkiaCanvas,colorSpaceXform)56 TEST(SkiaCanvas, colorSpaceXform) {
57     sk_sp<SkColorSpace> adobe = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
58                                                       SkNamedGamut::kAdobeRGB);
59 
60     SkImageInfo adobeInfo = SkImageInfo::Make(1, 1, kN32_SkColorType, kOpaque_SkAlphaType, adobe);
61     sk_sp<Bitmap> adobeBitmap = Bitmap::allocateHeapBitmap(adobeInfo);
62     SkBitmap adobeSkBitmap;
63     adobeBitmap->getSkBitmap(&adobeSkBitmap);
64     *adobeSkBitmap.getAddr32(0, 0) = 0xFF0000F0;  // Opaque, almost fully-red
65 
66     SkImageInfo info = adobeInfo.makeColorSpace(SkColorSpace::MakeSRGB());
67     sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
68     SkBitmap skBitmap;
69     bitmap->getSkBitmap(&skBitmap);
70 
71     // Create a software sRGB canvas.
72     SkiaCanvas canvas(skBitmap);
73     canvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
74     // The result should be fully red, since we convert to sRGB at draw time.
75     ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0));
76 
77     // Create a software canvas with an Adobe color space.
78     SkiaCanvas adobeSkCanvas(adobeSkBitmap);
79     adobeSkCanvas.drawBitmap(*bitmap, 0, 0, nullptr);
80     // The result should be less than fully red, since we convert to Adobe RGB at draw time.
81     ASSERT_EQ(0xFF0000DC, *adobeSkBitmap.getAddr32(0, 0));
82 
83     // Test picture recording.
84     SkPictureRecorder recorder;
85     SkCanvas* skPicCanvas = recorder.beginRecording(1, 1);
86     SkiaCanvas picCanvas(skPicCanvas);
87     picCanvas.drawBitmap(*adobeBitmap, 0, 0, nullptr);
88     sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
89 
90     // Playback to a software sRGB canvas.  The result should be fully red.
91     canvas.drawPicture(*picture);
92     ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0));
93 }
94 
TEST(SkiaCanvas,captureCanvasState)95 TEST(SkiaCanvas, captureCanvasState) {
96     // Create a software canvas.
97     SkImageInfo info = SkImageInfo::Make(1, 1, kN32_SkColorType, kOpaque_SkAlphaType);
98     sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(info);
99     SkBitmap skBitmap;
100     bitmap->getSkBitmap(&skBitmap);
101     skBitmap.eraseColor(0);
102     SkiaCanvas canvas(skBitmap);
103 
104     // Translate, then capture and verify the CanvasState.
105     canvas.translate(1.0f, 1.0f);
106     SkCanvasState* state = canvas.captureCanvasState();
107     ASSERT_NE(state, nullptr);
108     std::unique_ptr<SkCanvas> newCanvas = SkCanvasStateUtils::MakeFromCanvasState(state);
109     ASSERT_NE(newCanvas.get(), nullptr);
110     newCanvas->translate(-1.0f, -1.0f);
111     ASSERT_TRUE(newCanvas->getTotalMatrix().isIdentity());
112     SkCanvasStateUtils::ReleaseCanvasState(state);
113 
114     // Create a picture canvas.
115     SkPictureRecorder recorder;
116     SkCanvas* skPicCanvas = recorder.beginRecording(1, 1);
117     SkiaCanvas picCanvas(skPicCanvas);
118     state = picCanvas.captureCanvasState();
119 
120     // Verify that we cannot get the CanvasState.
121     ASSERT_EQ(state, nullptr);
122 }
123