blob: a1a99ca912db98b2e009fbeab7575d0625afe6cd [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/lib/escher/debug/debug_rects.h"
#include "src/ui/lib/escher/defaults/default_shader_program_factory.h"
#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/geometry/bounding_box.h"
#include "src/ui/lib/escher/paper/paper_renderer.h"
#include "src/ui/lib/escher/paper/paper_renderer_static_config.h"
#include "src/ui/lib/escher/paper/paper_scene.h"
#include "src/ui/lib/escher/paper/paper_timestamp_graph.h"
#include "src/ui/lib/escher/renderer/batch_gpu_uploader.h"
#include "src/ui/lib/escher/test/common/paper_renderer_test.h"
#include "src/ui/lib/escher/types/color.h"
#include "src/ui/lib/escher/types/color_histogram.h"
#include "src/ui/lib/escher/util/image_utils.h"
#include <vulkan/vulkan.hpp>
namespace escher {
namespace test {
class DebugShapeTest : public PaperRendererTest {
public:
// Used by tests that call DebugRects::Color when drawing.
int32_t GetColoredData(DebugRects::Color kColor) {
auto bytes = GetPixelData();
const ColorHistogram<ColorBgra> histogram(bytes.data(), kFramebufferWidth * kFramebufferHeight);
EXPECT_EQ(2U, histogram.size());
ColorRgba c = DebugRects::colorData[kColor];
ColorBgra b = ColorBgra(c.r, c.g, c.b, c.a);
return histogram[b];
}
};
VK_TEST_F(DebugShapeTest, Text) {
constexpr uint32_t kNumPixelsPerGlyph = 7 * 7;
constexpr ColorBgra kWhite(255, 255, 255, 255);
constexpr ColorBgra kBlack(0, 0, 0, 255);
constexpr ColorBgra kTransparentBlack(0, 0, 0, 0);
// Expects PaperRenderer's background color to be transparent.
for (int32_t scale = 1; scale <= 4; ++scale) {
SetupFrame();
// |expected_black| is the total number of black pixels *within* the glyphs
// *before* scaling. In other words, black background pixels outside of the
// glyph bounds are not counted. Also, consider the glyph "!" which has 4
// black pixels all in one vertical column (3 black, 1 white, 1 black)...
// if the scale is 2 then both the width and height are doubled so the
// number of black pixels in the glyph after scaling is 16.
std::function<void(std::string, size_t)> draw_and_check_histogram = [&](std::string glyphs,
size_t expected_black) {
BeginRenderingFrame();
renderer()->DrawDebugText(glyphs, {0, 10 * scale}, scale);
EndRenderingFrame();
const int32_t scale_squared = scale * scale;
size_t expected_white =
(glyphs.length() * kNumPixelsPerGlyph - expected_black) * scale_squared;
auto bytes = GetPixelData();
const ColorHistogram<ColorBgra> histogram(bytes.data(),
kFramebufferWidth * kFramebufferHeight);
EXPECT_EQ(3U, histogram.size());
EXPECT_EQ(histogram[kWhite], expected_white)
<< "FAILED WHILE DRAWING \"" << glyphs << "\" AT SCALE: " << scale;
EXPECT_EQ(histogram[kBlack], expected_black * scale_squared)
<< "FAILED WHILE DRAWING \"" << glyphs << "\" AT SCALE: " << scale;
EXPECT_EQ(histogram[kTransparentBlack],
kNumFramebufferPixels - (scale_squared * kNumPixelsPerGlyph * glyphs.length()));
};
// Each time, we draw on top of the previous glyph.
draw_and_check_histogram("1", 5);
draw_and_check_histogram("A", 12);
draw_and_check_histogram("!", 4);
// Draw a glyph that has not been defined, it should draw a black square.
draw_and_check_histogram("Z", 25);
// Draw several glyphs next to each other.
draw_and_check_histogram(" 1A!", 0 + 5 + 12 + 4);
TeardownFrame();
}
escher()->vk_device().waitIdle();
ASSERT_TRUE(escher()->Cleanup());
}
// Tests that vertical and horizontal lines of a specific color are drawn correctly when called.
// It does this by checking the number of pixels drawn of the specified color against what is
// expected. Colors are created in debug_rects.h and take the format |kColor|.
VK_TEST_F(DebugShapeTest, Lines) {
for (int32_t thickness = 1; thickness <= 4; ++thickness) {
SetupFrame();
// Draws verticle and horizontal lines of |KColor| starting at (0, 0) and going to |endCoord|.
std::function<void(DebugRects::Color, uint8_t)> draw_and_check_histogram =
[&](DebugRects::Color kColor, uint8_t endCoord) {
auto expected_colored = endCoord * thickness;
{
BeginRenderingFrame();
renderer()->DrawVLine(kColor, 0, 0, endCoord, thickness);
EndRenderingFrame();
}
EXPECT_EQ(expected_colored, GetColoredData(kColor))
<< "FAILED WHILE DRAWING VERTICAL LINE OF COLOR \"" << kColor
<< "\" AT THICKNESS: " << thickness;
{
BeginRenderingFrame();
renderer()->DrawHLine(kColor, 0, 0, endCoord, thickness);
EndRenderingFrame();
}
EXPECT_EQ(expected_colored, GetColoredData(kColor))
<< "FAILED WHILE DRAWING HORIZONTAL LINE OF COLOR \"" << kColor
<< "\" AT THICKNESS: " << thickness;
};
draw_and_check_histogram(escher::DebugRects::kPurple, (uint8_t)500);
draw_and_check_histogram(escher::DebugRects::kRed, (uint8_t)800);
draw_and_check_histogram(escher::DebugRects::kYellow, (uint8_t)200);
TeardownFrame();
}
escher()->vk_device().waitIdle();
ASSERT_TRUE(escher()->Cleanup());
}
// Tests drawing fake data used by the Debug Graph.
VK_TEST_F(DebugShapeTest, PaperTimestampGraph) {
int16_t expected_colored = 0;
PaperTimestampGraph graph;
for (int32_t i = 1; i <= 10; ++i) {
SetupFrame();
// Creates an escher Timestamp where |done_time| > |start_time| so that the values are
// not negative. All other values are 0 to simplify the test.
std::function<void(int8_t, int8_t)> draw_and_check_histogram = [&](uint8_t start_time,
uint8_t done_time) {
EXPECT_TRUE(depth_buffer() || i == 1);
BeginRenderingFrame();
EXPECT_TRUE(depth_buffer());
PaperRenderer::Timestamp ts;
ts.latch_point = 0;
ts.update_done = 0;
ts.render_start = start_time;
ts.render_done = done_time;
ts.target_present = 0;
ts.actual_present = 0;
graph.AddTimestamp(ts);
constexpr uint32_t kGraphHeight = 500;
constexpr uint32_t kGraphWidth = 500;
graph.DrawGraphContentOn(renderer(), {{0, 0}, {kGraphWidth, kGraphHeight}});
EndRenderingFrame();
int16_t render_time = done_time - start_time;
const int16_t h_interval = kGraphHeight / 35;
const int16_t w_interval = PaperTimestampGraph::kSampleLineThickness;
expected_colored += (render_time * h_interval) * w_interval;
auto returned_colored = GetColoredData(escher::DebugRects::kRed);
EXPECT_EQ(expected_colored, returned_colored)
<< "FAILED WHILE DRAWING DEBUG DATA FOR RENDER TIME " << render_time;
};
int8_t end = i * 2;
draw_and_check_histogram(1, end);
TeardownFrame();
}
escher()->vk_device().waitIdle();
ASSERT_TRUE(escher()->Cleanup());
}
} // namespace test
} // namespace escher