/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <gtest/gtest.h> #include "Glop.h" #include "GlopBuilder.h" #include "Rect.h" #include "tests/common/TestUtils.h" #include "utils/Color.h" #include <SkPaint.h> using namespace android::uirenderer; static void expectFillEq(Glop::Fill& expectedFill, Glop::Fill& builtFill) { EXPECT_EQ(expectedFill.colorEnabled, builtFill.colorEnabled); if (expectedFill.colorEnabled) EXPECT_EQ(expectedFill.color, builtFill.color); EXPECT_EQ(expectedFill.filterMode, builtFill.filterMode); if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Blend) { EXPECT_EQ(expectedFill.filter.color, builtFill.filter.color); } else if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Matrix) { Glop::Fill::Filter::Matrix& expectedMatrix = expectedFill.filter.matrix; Glop::Fill::Filter::Matrix& builtMatrix = expectedFill.filter.matrix; EXPECT_TRUE(std::memcmp(expectedMatrix.matrix, builtMatrix.matrix, sizeof(Glop::Fill::Filter::Matrix::matrix))); EXPECT_TRUE(std::memcmp(expectedMatrix.vector, builtMatrix.vector, sizeof(Glop::Fill::Filter::Matrix::vector))); } EXPECT_EQ(expectedFill.skiaShaderData.skiaShaderType, builtFill.skiaShaderData.skiaShaderType); EXPECT_EQ(expectedFill.texture.clamp, builtFill.texture.clamp); EXPECT_EQ(expectedFill.texture.filter, builtFill.texture.filter); EXPECT_EQ(expectedFill.texture.target, builtFill.texture.target); EXPECT_EQ(expectedFill.texture.textureTransform, builtFill.texture.textureTransform); } static void expectBlendEq(Glop::Blend& expectedBlend, Glop::Blend& builtBlend) { EXPECT_EQ(expectedBlend.src, builtBlend.src); EXPECT_EQ(expectedBlend.dst, builtBlend.dst); } static void expectMeshEq(Glop::Mesh& expectedMesh, Glop::Mesh& builtMesh) { EXPECT_EQ(expectedMesh.elementCount, builtMesh.elementCount); EXPECT_EQ(expectedMesh.primitiveMode, builtMesh.primitiveMode); EXPECT_EQ(expectedMesh.indices.indices, builtMesh.indices.indices); EXPECT_EQ(expectedMesh.indices.bufferObject, builtMesh.indices.bufferObject); EXPECT_EQ(expectedMesh.vertices.attribFlags, builtMesh.vertices.attribFlags); EXPECT_EQ(expectedMesh.vertices.bufferObject, builtMesh.vertices.bufferObject); EXPECT_EQ(expectedMesh.vertices.color, builtMesh.vertices.color); EXPECT_EQ(expectedMesh.vertices.position, builtMesh.vertices.position); EXPECT_EQ(expectedMesh.vertices.stride, builtMesh.vertices.stride); EXPECT_EQ(expectedMesh.vertices.texCoord, builtMesh.vertices.texCoord); if (builtMesh.vertices.position) { for (int i = 0; i < 4; i++) { TextureVertex& expectedVertex = expectedMesh.mappedVertices[i]; TextureVertex& builtVertex = builtMesh.mappedVertices[i]; EXPECT_EQ(expectedVertex.u, builtVertex.u); EXPECT_EQ(expectedVertex.v, builtVertex.v); EXPECT_EQ(expectedVertex.x, builtVertex.x); EXPECT_EQ(expectedVertex.y, builtVertex.y); } } } static void expectTransformEq(Glop::Transform& expectedTransform, Glop::Transform& builtTransform) { EXPECT_EQ(expectedTransform.canvas, builtTransform.canvas); EXPECT_EQ(expectedTransform.modelView, builtTransform.modelView); EXPECT_EQ(expectedTransform.transformFlags, expectedTransform.transformFlags); } static void expectGlopEq(Glop& expectedGlop, Glop& builtGlop) { #if !HWUI_NEW_OPS EXPECT_EQ(expectedGlop.bounds, builtGlop.bounds); #endif expectBlendEq(expectedGlop.blend, builtGlop.blend); expectFillEq(expectedGlop.fill, builtGlop.fill); expectMeshEq(expectedGlop.mesh, builtGlop.mesh); expectTransformEq(expectedGlop.transform, builtGlop.transform); } static std::unique_ptr<Glop> blackUnitQuadGlop(RenderState& renderState) { std::unique_ptr<Glop> glop(new Glop()); glop->blend = { GL_ZERO, GL_ZERO }; glop->mesh.elementCount = 4; glop->mesh.primitiveMode = GL_TRIANGLE_STRIP; glop->mesh.indices.indices = nullptr; glop->mesh.indices.bufferObject = GL_ZERO; glop->mesh.vertices = { renderState.meshState().getUnitQuadVBO(), VertexAttribFlags::None, nullptr, nullptr, nullptr, kTextureVertexStride }; glop->transform.modelView.loadIdentity(); glop->fill.colorEnabled = true; glop->fill.color.set(Color::Black); glop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType; glop->fill.filterMode = ProgramDescription::ColorFilterMode::None; glop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr }; return glop; } RENDERTHREAD_TEST(GlopBuilder, rectSnapTest) { RenderState& renderState = renderThread.renderState(); Caches& caches = Caches::getInstance(); SkPaint paint; Rect dest(1, 1, 100, 100); Matrix4 simpleTranslate; simpleTranslate.loadTranslate(0.7, 0.7, 0); Glop glop; GlopBuilder(renderState, caches, &glop) .setRoundRectClipState(nullptr) .setMeshUnitQuad() .setFillPaint(paint, 1.0f) .setTransform(simpleTranslate, TransformFlags::None) .setModelViewMapUnitToRectSnap(dest) .build(); std::unique_ptr<Glop> goldenGlop(blackUnitQuadGlop(renderState)); // Rect(1,1,100,100) is the set destination, // so unit quad should be translated by (1,1) and scaled by (99, 99) // Tricky part: because translate (0.7, 0.7) and snapping were set in glopBuilder, // unit quad also should be translate by additional (0.3, 0.3) to snap to exact pixels. goldenGlop->transform.modelView.loadTranslate(1.3, 1.3, 0); goldenGlop->transform.modelView.scale(99, 99, 1); #if !HWUI_NEW_OPS goldenGlop->bounds = android::uirenderer::Rect(1.70, 1.70, 100.70, 100.70); #endif goldenGlop->transform.canvas = simpleTranslate; goldenGlop->fill.texture.filter = GL_NEAREST; expectGlopEq(*goldenGlop, glop); }