| // Copyright 2020 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 "base_view.h" |
| |
| #include <lib/trace/event.h> |
| #include <lib/ui/scenic/cpp/commands.h> |
| |
| #include <cmath> |
| |
| namespace frame_compression { |
| |
| namespace { |
| |
| constexpr float kDisplayHeight = 50; |
| constexpr float kInitialWindowXPos = 320; |
| constexpr float kInitialWindowYPos = 240; |
| |
| // Inspect values. |
| constexpr char kBaseView[] = "base_view"; |
| constexpr char kWidth[] = "width"; |
| constexpr char kHeight[] = "height"; |
| |
| } // namespace |
| |
| BaseView::BaseView(scenic::ViewContext context, const std::string& debug_name, uint32_t width, |
| uint32_t height, inspect::Node inspect_node) |
| : scenic::BaseView(std::move(context), debug_name), |
| width_(width), |
| height_(height), |
| material_(session()), |
| top_inspect_node_(std::move(inspect_node)), |
| next_color_offset_(height / 2), |
| node_(session()), |
| inspect_node_( |
| top_inspect_node_.CreateLazyValues(kBaseView, [this] { return PopulateStats(); })) { |
| // Create a rectangle shape to display on. |
| scenic::Rectangle shape(session(), width_, height_); |
| |
| node_.SetShape(shape); |
| node_.SetMaterial(material_); |
| root_node().AddChild(node_); |
| |
| // Translation of 0, 0 is the middle of the screen |
| node_.SetTranslation(kInitialWindowXPos, kInitialWindowYPos, -kDisplayHeight); |
| } |
| |
| png_structp BaseView::CreatePngReadStruct(FILE* png_fp, png_infop* info_ptr_ptr) { |
| fseek(png_fp, 0, SEEK_SET); |
| uint8_t header[8]; |
| fread(header, 1, 8, png_fp); |
| FX_CHECK(png_sig_cmp(header, 0, 8) == 0) << "File is not recognized as a PNG file"; |
| png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); |
| FX_CHECK(png_ptr) << "png_create_read_struct failed"; |
| if (setjmp(png_jmpbuf(png_ptr))) { |
| FX_CHECK(false) << "error during png_init_io"; |
| } |
| png_init_io(png_ptr, png_fp); |
| png_set_sig_bytes(png_ptr, 8); |
| png_infop info_ptr = png_create_info_struct(png_ptr); |
| FX_CHECK(info_ptr) << "png_create_info_struct failed"; |
| png_read_info(png_ptr, info_ptr); |
| FX_CHECK(png_get_interlace_type(png_ptr, info_ptr) == PNG_INTERLACE_NONE); |
| png_byte color_type = png_get_color_type(png_ptr, info_ptr); |
| FX_CHECK(color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA); |
| if (color_type == PNG_COLOR_TYPE_RGB) { |
| png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); |
| } |
| png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr); |
| if (bit_depth < 8) { |
| png_set_packing(png_ptr); |
| } else if (bit_depth == 16) { |
| png_set_strip_16(png_ptr); |
| png_set_swap(png_ptr); |
| } |
| *info_ptr_ptr = info_ptr; |
| return png_ptr; |
| } |
| |
| void BaseView::DestroyPngReadStruct(png_structp png_ptr, png_infop info_ptr) { |
| png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); |
| } |
| |
| uint32_t BaseView::GetNextImageIndex() { |
| const auto rv = next_image_index_; |
| next_image_index_ = (next_image_index_ + 1) % kNumImages; |
| return rv; |
| } |
| |
| uint32_t BaseView::GetNextColorOffset() { |
| const auto rv = next_color_offset_; |
| next_color_offset_ = (next_color_offset_ + 1) % height_; |
| return rv; |
| } |
| |
| uint32_t BaseView::GetNextFrameNumber() { |
| const auto rv = next_frame_number_; |
| next_frame_number_ = next_frame_number_ + 1; |
| return rv; |
| } |
| |
| void BaseView::Animate(fuchsia::images::PresentationInfo presentation_info) { |
| // Compute the amount of time that has elapsed since the view was created. |
| double seconds = static_cast<double>(presentation_info.presentation_time) / 1'000'000'000; |
| |
| const float kHalfWidth = logical_size().x * 0.5f; |
| const float kHalfHeight = logical_size().y * 0.5f; |
| |
| // Compute the translation for the window to swirl around the screen. |
| node_.SetTranslation(kHalfWidth * (1. + .1 * sin(seconds * 0.8)), |
| kHalfHeight * (1. + .1 * sin(seconds * 0.6)), -kDisplayHeight); |
| } |
| |
| fit::promise<inspect::Inspector> BaseView::PopulateStats() const { |
| inspect::Inspector inspector; |
| |
| inspector.GetRoot().CreateUint(kWidth, width_, &inspector); |
| inspector.GetRoot().CreateUint(kHeight, height_, &inspector); |
| |
| return fit::make_ok_promise(std::move(inspector)); |
| } |
| |
| } // namespace frame_compression |