blob: 189b9d93a9e439019c0ab4230befffa4c6153af5 [file] [log] [blame]
// Copyright 2017 The Chromium 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 "chrome/browser/vr/test/ui_pixel_test.h"
#include "build/build_config.h"
#include "chrome/browser/vr/browser_ui_interface.h"
#include "chrome/browser/vr/model/model.h"
#include "chrome/browser/vr/test/animation_utils.h"
#include "chrome/browser/vr/test/constants.h"
#include "chrome/browser/vr/ui_browser_interface.h"
#include "chrome/browser/vr/ui_input_manager.h"
#include "chrome/browser/vr/ui_renderer.h"
#include "chrome/browser/vr/ui_scene.h"
#include "third_party/WebKit/public/platform/WebGestureEvent.h"
#include "third_party/skia/include/core/SkImageEncoder.h"
#include "third_party/skia/include/core/SkStream.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/test/gl_test_helper.h"
namespace vr {
UiPixelTest::UiPixelTest() : frame_buffer_size_(kPixelHalfScreen) {}
UiPixelTest::~UiPixelTest() = default;
void UiPixelTest::SetUp() {
// TODO(crbug/771794): Test temporarily disabled on Windows because it crashes
// on trybots. Fix before enabling Windows support.
#ifndef OS_WIN
gl_test_environment_ =
std::make_unique<GlTestEnvironment>(frame_buffer_size_);
// Make content texture.
content_texture_ = gl::GLTestHelper::CreateTexture(GL_TEXTURE_2D);
content_overlay_texture_ = gl::GLTestHelper::CreateTexture(GL_TEXTURE_2D);
// TODO(tiborg): Make GL_TEXTURE_EXTERNAL_OES texture for content and fill it
// with fake content.
ASSERT_EQ(glGetError(), (GLenum)GL_NO_ERROR);
browser_ = std::make_unique<MockUiBrowserInterface>();
#endif
}
void UiPixelTest::TearDown() {
// TODO(crbug/771794): Test temporarily disabled on Windows because it crashes
// on trybots. Fix before enabling Windows support.
#ifndef OS_WIN
ui_.reset();
glDeleteTextures(1, &content_texture_);
gl_test_environment_.reset();
#endif
}
void UiPixelTest::MakeUi(const UiInitialState& ui_initial_state,
const ToolbarState& toolbar_state) {
ui_ = std::make_unique<Ui>(browser_.get(), nullptr, nullptr, nullptr,
ui_initial_state);
ui_->OnGlInitialized(content_texture_,
vr::UiElementRenderer::kTextureLocationLocal,
content_overlay_texture_,
vr::UiElementRenderer::kTextureLocationLocal, true);
ui_->GetBrowserUiWeakPtr()->SetToolbarState(toolbar_state);
}
void UiPixelTest::DrawUi(const gfx::Vector3dF& laser_direction,
const gfx::Point3F& laser_origin,
UiInputManager::ButtonState button_state,
float controller_opacity,
const gfx::Transform& controller_transform,
const gfx::Transform& view_matrix,
const gfx::Transform& proj_matrix) {
ControllerModel controller_model;
controller_model.laser_direction = kForwardVector;
controller_model.transform = controller_transform;
controller_model.opacity = controller_opacity;
controller_model.laser_origin = laser_origin;
controller_model.touchpad_button_state = button_state;
controller_model.app_button_state = UiInputManager::ButtonState::UP;
controller_model.home_button_state = UiInputManager::ButtonState::UP;
RenderInfo render_info;
render_info.head_pose = view_matrix;
render_info.left_eye_model.view_matrix = view_matrix;
render_info.left_eye_model.proj_matrix = proj_matrix;
render_info.left_eye_model.view_proj_matrix = proj_matrix * view_matrix;
render_info.right_eye_model = render_info.left_eye_model;
render_info.surface_texture_size = frame_buffer_size_;
render_info.left_eye_model.viewport = {0, 0, frame_buffer_size_.width(),
frame_buffer_size_.height()};
render_info.right_eye_model.viewport = {0, 0, 0, 0};
GestureList gesture_list;
ReticleModel reticle_model;
EXPECT_TRUE(
ui_->scene()->OnBeginFrame(base::TimeTicks(), render_info.head_pose));
ui_->input_manager()->HandleInput(MsToTicks(1), render_info, controller_model,
&reticle_model, &gesture_list);
ui_->OnControllerUpdated(controller_model, reticle_model);
ui_->ui_renderer()->Draw(render_info);
// We produce GL errors while rendering. Clear them all so that we can check
// for errors of subsequent calls.
// TODO(768905): Fix producing errors while rendering.
while (glGetError() != GL_NO_ERROR) {
}
}
std::unique_ptr<SkBitmap> UiPixelTest::SaveCurrentFrameBufferToSkBitmap() {
// Create buffer.
std::unique_ptr<SkBitmap> bitmap = std::make_unique<SkBitmap>();
if (!bitmap->tryAllocN32Pixels(frame_buffer_size_.width(),
frame_buffer_size_.height(), false)) {
return nullptr;
}
SkPixmap pixmap;
if (!bitmap->peekPixels(&pixmap)) {
return nullptr;
}
// Read pixels from frame buffer.
glReadPixels(0, 0, frame_buffer_size_.width(), frame_buffer_size_.height(),
GL_RGBA, GL_UNSIGNED_BYTE, pixmap.writable_addr());
if (glGetError() != GL_NO_ERROR) {
return nullptr;
}
// Flip image vertically since SkBitmap expects the pixels in a different
// order.
for (int col = 0; col < frame_buffer_size_.width(); col++) {
for (int row = 0; row < frame_buffer_size_.height() / 2; row++) {
std::swap(
*pixmap.writable_addr32(col, row),
*pixmap.writable_addr32(col, frame_buffer_size_.height() - row - 1));
}
}
return bitmap;
}
bool UiPixelTest::SaveSkBitmapToPng(const SkBitmap& bitmap,
const std::string& filename) {
SkFILEWStream stream(filename.c_str());
if (!stream.isValid()) {
return false;
}
if (!SkEncodeImage(&stream, bitmap, SkEncodedImageFormat::kPNG, 100)) {
return false;
}
return true;
}
} // namespace vr