blob: 35a45ab7d6b8ed02af0ffbb87c5bde09909624af [file] [log] [blame]
// 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.0f;
constexpr float kInitialWindowXPos = 320.0f;
constexpr float kInitialWindowYPos = 240.0f;
// 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(), static_cast<float>(width_), static_cast<float>(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 ||
color_type == PNG_COLOR_TYPE_PALETTE || color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA);
if (color_type == PNG_COLOR_TYPE_PALETTE) {
png_set_palette_to_rgb(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY) {
png_set_expand_gray_1_2_4_to_8(png_ptr);
}
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
png_set_gray_to_rgb(png_ptr);
}
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.
float seconds = static_cast<float>(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.f + .1f * sin(seconds * 0.8f)),
kHalfHeight * (1.f + .1f * sin(seconds * 0.6f)), -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