1f42bf3e2573bccb01babec448f925e9395bf224csergeyv/*
2f42bf3e2573bccb01babec448f925e9395bf224csergeyv * Copyright (C) 2016 The Android Open Source Project
3f42bf3e2573bccb01babec448f925e9395bf224csergeyv *
4f42bf3e2573bccb01babec448f925e9395bf224csergeyv * Licensed under the Apache License, Version 2.0 (the "License");
5f42bf3e2573bccb01babec448f925e9395bf224csergeyv * you may not use this file except in compliance with the License.
6f42bf3e2573bccb01babec448f925e9395bf224csergeyv * You may obtain a copy of the License at
7f42bf3e2573bccb01babec448f925e9395bf224csergeyv *
8f42bf3e2573bccb01babec448f925e9395bf224csergeyv *      http://www.apache.org/licenses/LICENSE-2.0
9f42bf3e2573bccb01babec448f925e9395bf224csergeyv *
10f42bf3e2573bccb01babec448f925e9395bf224csergeyv * Unless required by applicable law or agreed to in writing, software
11f42bf3e2573bccb01babec448f925e9395bf224csergeyv * distributed under the License is distributed on an "AS IS" BASIS,
12f42bf3e2573bccb01babec448f925e9395bf224csergeyv * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f42bf3e2573bccb01babec448f925e9395bf224csergeyv * See the License for the specific language governing permissions and
14f42bf3e2573bccb01babec448f925e9395bf224csergeyv * limitations under the License.
15f42bf3e2573bccb01babec448f925e9395bf224csergeyv */
16f42bf3e2573bccb01babec448f925e9395bf224csergeyv
17f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include <gtest/gtest.h>
18f42bf3e2573bccb01babec448f925e9395bf224csergeyv
19f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include "Glop.h"
20f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include "GlopBuilder.h"
21f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include "Rect.h"
22f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include "tests/common/TestUtils.h"
23f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include "utils/Color.h"
24f42bf3e2573bccb01babec448f925e9395bf224csergeyv
25f42bf3e2573bccb01babec448f925e9395bf224csergeyv#include <SkPaint.h>
26f42bf3e2573bccb01babec448f925e9395bf224csergeyv
27f42bf3e2573bccb01babec448f925e9395bf224csergeyvusing namespace android::uirenderer;
28f42bf3e2573bccb01babec448f925e9395bf224csergeyv
29f42bf3e2573bccb01babec448f925e9395bf224csergeyvstatic void expectFillEq(Glop::Fill& expectedFill, Glop::Fill& builtFill) {
30f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedFill.colorEnabled, builtFill.colorEnabled);
31f42bf3e2573bccb01babec448f925e9395bf224csergeyv    if (expectedFill.colorEnabled)
32f42bf3e2573bccb01babec448f925e9395bf224csergeyv        EXPECT_EQ(expectedFill.color, builtFill.color);
33f42bf3e2573bccb01babec448f925e9395bf224csergeyv
34f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedFill.filterMode, builtFill.filterMode);
35f42bf3e2573bccb01babec448f925e9395bf224csergeyv    if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Blend) {
36f42bf3e2573bccb01babec448f925e9395bf224csergeyv        EXPECT_EQ(expectedFill.filter.color, builtFill.filter.color);
37f42bf3e2573bccb01babec448f925e9395bf224csergeyv    } else if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Matrix) {
38f42bf3e2573bccb01babec448f925e9395bf224csergeyv        Glop::Fill::Filter::Matrix& expectedMatrix = expectedFill.filter.matrix;
39f42bf3e2573bccb01babec448f925e9395bf224csergeyv        Glop::Fill::Filter::Matrix& builtMatrix = expectedFill.filter.matrix;
40f42bf3e2573bccb01babec448f925e9395bf224csergeyv        EXPECT_TRUE(std::memcmp(expectedMatrix.matrix, builtMatrix.matrix,
41f42bf3e2573bccb01babec448f925e9395bf224csergeyv                sizeof(Glop::Fill::Filter::Matrix::matrix)));
42f42bf3e2573bccb01babec448f925e9395bf224csergeyv        EXPECT_TRUE(std::memcmp(expectedMatrix.vector, builtMatrix.vector,
43f42bf3e2573bccb01babec448f925e9395bf224csergeyv                sizeof(Glop::Fill::Filter::Matrix::vector)));
44f42bf3e2573bccb01babec448f925e9395bf224csergeyv    }
45f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedFill.skiaShaderData.skiaShaderType, builtFill.skiaShaderData.skiaShaderType);
46f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedFill.texture.clamp, builtFill.texture.clamp);
47f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedFill.texture.filter, builtFill.texture.filter);
482a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv    EXPECT_TRUE((expectedFill.texture.texture && builtFill.texture.texture)
492a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv            || (!expectedFill.texture.texture && !builtFill.texture.texture));
502a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv    if (expectedFill.texture.texture) {
512a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv        EXPECT_EQ(expectedFill.texture.texture->target(), builtFill.texture.texture->target());
522a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv    }
53f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedFill.texture.textureTransform, builtFill.texture.textureTransform);
54f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
55f42bf3e2573bccb01babec448f925e9395bf224csergeyv
56f42bf3e2573bccb01babec448f925e9395bf224csergeyvstatic void expectBlendEq(Glop::Blend& expectedBlend, Glop::Blend& builtBlend) {
57f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedBlend.src, builtBlend.src);
58f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedBlend.dst, builtBlend.dst);
59f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
60f42bf3e2573bccb01babec448f925e9395bf224csergeyv
61f42bf3e2573bccb01babec448f925e9395bf224csergeyvstatic void expectMeshEq(Glop::Mesh& expectedMesh, Glop::Mesh& builtMesh) {
62f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.elementCount, builtMesh.elementCount);
63f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.primitiveMode, builtMesh.primitiveMode);
64f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.indices.indices, builtMesh.indices.indices);
65f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.indices.bufferObject, builtMesh.indices.bufferObject);
66f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.vertices.attribFlags, builtMesh.vertices.attribFlags);
67f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.vertices.bufferObject, builtMesh.vertices.bufferObject);
68f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.vertices.color, builtMesh.vertices.color);
69f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.vertices.position, builtMesh.vertices.position);
70f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.vertices.stride, builtMesh.vertices.stride);
71f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedMesh.vertices.texCoord, builtMesh.vertices.texCoord);
72f42bf3e2573bccb01babec448f925e9395bf224csergeyv
73f42bf3e2573bccb01babec448f925e9395bf224csergeyv    if (builtMesh.vertices.position) {
74f42bf3e2573bccb01babec448f925e9395bf224csergeyv        for (int i = 0; i < 4; i++) {
75f42bf3e2573bccb01babec448f925e9395bf224csergeyv            TextureVertex& expectedVertex = expectedMesh.mappedVertices[i];
76f42bf3e2573bccb01babec448f925e9395bf224csergeyv            TextureVertex& builtVertex = builtMesh.mappedVertices[i];
77f42bf3e2573bccb01babec448f925e9395bf224csergeyv            EXPECT_EQ(expectedVertex.u, builtVertex.u);
78f42bf3e2573bccb01babec448f925e9395bf224csergeyv            EXPECT_EQ(expectedVertex.v, builtVertex.v);
79f42bf3e2573bccb01babec448f925e9395bf224csergeyv            EXPECT_EQ(expectedVertex.x, builtVertex.x);
80f42bf3e2573bccb01babec448f925e9395bf224csergeyv            EXPECT_EQ(expectedVertex.y, builtVertex.y);
81f42bf3e2573bccb01babec448f925e9395bf224csergeyv        }
82f42bf3e2573bccb01babec448f925e9395bf224csergeyv    }
83f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
84f42bf3e2573bccb01babec448f925e9395bf224csergeyv
85f42bf3e2573bccb01babec448f925e9395bf224csergeyvstatic void expectTransformEq(Glop::Transform& expectedTransform, Glop::Transform& builtTransform) {
86f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedTransform.canvas, builtTransform.canvas);
87f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedTransform.modelView, builtTransform.modelView);
88f42bf3e2573bccb01babec448f925e9395bf224csergeyv    EXPECT_EQ(expectedTransform.transformFlags, expectedTransform.transformFlags);
89f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
90f42bf3e2573bccb01babec448f925e9395bf224csergeyv
91f42bf3e2573bccb01babec448f925e9395bf224csergeyvstatic void expectGlopEq(Glop& expectedGlop, Glop& builtGlop) {
92f42bf3e2573bccb01babec448f925e9395bf224csergeyv    expectBlendEq(expectedGlop.blend, builtGlop.blend);
93f42bf3e2573bccb01babec448f925e9395bf224csergeyv    expectFillEq(expectedGlop.fill, builtGlop.fill);
94f42bf3e2573bccb01babec448f925e9395bf224csergeyv    expectMeshEq(expectedGlop.mesh, builtGlop.mesh);
95f42bf3e2573bccb01babec448f925e9395bf224csergeyv    expectTransformEq(expectedGlop.transform, builtGlop.transform);
96f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
97f42bf3e2573bccb01babec448f925e9395bf224csergeyv
98f42bf3e2573bccb01babec448f925e9395bf224csergeyvstatic std::unique_ptr<Glop> blackUnitQuadGlop(RenderState& renderState) {
99f42bf3e2573bccb01babec448f925e9395bf224csergeyv    std::unique_ptr<Glop> glop(new Glop());
100f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->blend = { GL_ZERO, GL_ZERO };
101f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->mesh.elementCount = 4;
102f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->mesh.primitiveMode = GL_TRIANGLE_STRIP;
103f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->mesh.indices.indices = nullptr;
104f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->mesh.indices.bufferObject = GL_ZERO;
105f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->mesh.vertices = {
106f42bf3e2573bccb01babec448f925e9395bf224csergeyv            renderState.meshState().getUnitQuadVBO(),
107f42bf3e2573bccb01babec448f925e9395bf224csergeyv            VertexAttribFlags::None,
108f42bf3e2573bccb01babec448f925e9395bf224csergeyv            nullptr, nullptr, nullptr,
109f42bf3e2573bccb01babec448f925e9395bf224csergeyv            kTextureVertexStride };
110f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->transform.modelView.loadIdentity();
111f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->fill.colorEnabled = true;
112f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->fill.color.set(Color::Black);
113f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType;
114f42bf3e2573bccb01babec448f925e9395bf224csergeyv    glop->fill.filterMode = ProgramDescription::ColorFilterMode::None;
1152a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv    glop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
116f42bf3e2573bccb01babec448f925e9395bf224csergeyv    return glop;
117f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
118f42bf3e2573bccb01babec448f925e9395bf224csergeyv
11998c78dad1969e2321cfee2085faa55d95bba7e29Greg DanielRENDERTHREAD_OPENGL_PIPELINE_TEST(GlopBuilder, rectSnapTest) {
120f42bf3e2573bccb01babec448f925e9395bf224csergeyv    RenderState& renderState = renderThread.renderState();
121f42bf3e2573bccb01babec448f925e9395bf224csergeyv    Caches& caches = Caches::getInstance();
122f42bf3e2573bccb01babec448f925e9395bf224csergeyv    SkPaint paint;
123f42bf3e2573bccb01babec448f925e9395bf224csergeyv    Rect dest(1, 1, 100, 100);
124f42bf3e2573bccb01babec448f925e9395bf224csergeyv    Matrix4 simpleTranslate;
125f42bf3e2573bccb01babec448f925e9395bf224csergeyv    simpleTranslate.loadTranslate(0.7, 0.7, 0);
126f42bf3e2573bccb01babec448f925e9395bf224csergeyv    Glop glop;
127f42bf3e2573bccb01babec448f925e9395bf224csergeyv    GlopBuilder(renderState, caches, &glop)
128f42bf3e2573bccb01babec448f925e9395bf224csergeyv            .setRoundRectClipState(nullptr)
129f42bf3e2573bccb01babec448f925e9395bf224csergeyv            .setMeshUnitQuad()
130f42bf3e2573bccb01babec448f925e9395bf224csergeyv            .setFillPaint(paint, 1.0f)
131f42bf3e2573bccb01babec448f925e9395bf224csergeyv            .setTransform(simpleTranslate, TransformFlags::None)
132f42bf3e2573bccb01babec448f925e9395bf224csergeyv            .setModelViewMapUnitToRectSnap(dest)
133f42bf3e2573bccb01babec448f925e9395bf224csergeyv            .build();
134f42bf3e2573bccb01babec448f925e9395bf224csergeyv
135f42bf3e2573bccb01babec448f925e9395bf224csergeyv    std::unique_ptr<Glop> goldenGlop(blackUnitQuadGlop(renderState));
136f42bf3e2573bccb01babec448f925e9395bf224csergeyv    // Rect(1,1,100,100) is the set destination,
137f42bf3e2573bccb01babec448f925e9395bf224csergeyv    // so unit quad should be translated by (1,1) and scaled by (99, 99)
138f42bf3e2573bccb01babec448f925e9395bf224csergeyv    // Tricky part: because translate (0.7, 0.7) and snapping were set in glopBuilder,
139f42bf3e2573bccb01babec448f925e9395bf224csergeyv    // unit quad also should be translate by additional (0.3, 0.3) to snap to exact pixels.
140f42bf3e2573bccb01babec448f925e9395bf224csergeyv    goldenGlop->transform.modelView.loadTranslate(1.3, 1.3, 0);
141f42bf3e2573bccb01babec448f925e9395bf224csergeyv    goldenGlop->transform.modelView.scale(99, 99, 1);
142f42bf3e2573bccb01babec448f925e9395bf224csergeyv    goldenGlop->transform.canvas = simpleTranslate;
143f42bf3e2573bccb01babec448f925e9395bf224csergeyv    goldenGlop->fill.texture.filter = GL_NEAREST;
144f42bf3e2573bccb01babec448f925e9395bf224csergeyv    expectGlopEq(*goldenGlop, glop);
145f42bf3e2573bccb01babec448f925e9395bf224csergeyv}
146