#include "chrome/browser/vr/ui_renderer.h"
#include "base/trace_event/trace_event.h"
#include "chrome/browser/vr/elements/ui_element.h"
#include "chrome/browser/vr/render_info.h"
#include "chrome/browser/vr/ui_element_renderer.h"
#include "chrome/browser/vr/ui_scene.h"
#include "device/vr/gl_bindings.h"
namespace vr {
UiRenderer::UiRenderer(UiScene* scene, UiElementRenderer* ui_element_renderer)
: scene_(scene), ui_element_renderer_(ui_element_renderer) {}
UiRenderer::~UiRenderer() = default;
void UiRenderer::Draw(const RenderInfo& render_info) {
glEnable(GL_CULL_FACE);
DrawUiView(render_info, scene_->GetElementsToDraw());
}
void UiRenderer::DrawWebVrOverlayForeground(const RenderInfo& render_info) {
glEnable(GL_CULL_FACE);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
DrawUiView(render_info, scene_->GetWebVrOverlayElementsToDraw());
}
void UiRenderer::DrawUiView(const RenderInfo& render_info,
const std::vector<const UiElement*>& elements) {
if (elements.empty())
return;
TRACE_EVENT0("gpu", "UiRenderer::DrawUiView");
auto sorted_elements = GetElementsInDrawOrder(elements);
for (auto& camera_model :
{render_info.left_eye_model, render_info.right_eye_model}) {
glViewport(camera_model.viewport.x(), camera_model.viewport.y(),
camera_model.viewport.width(), camera_model.viewport.height());
DrawElements(camera_model, sorted_elements, render_info);
}
}
void UiRenderer::DrawElements(const CameraModel& camera_model,
const std::vector<const UiElement*>& elements,
const RenderInfo& render_info) {
if (elements.empty()) {
return;
}
for (const auto* element : elements) {
DrawElement(camera_model, *element);
}
ui_element_renderer_->Flush();
}
void UiRenderer::DrawElement(const CameraModel& camera_model,
const UiElement& element) {
DCHECK_GE(element.draw_phase(), 0);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
element.Render(ui_element_renderer_, camera_model);
}
std::vector<const UiElement*> UiRenderer::GetElementsInDrawOrder(
const std::vector<const UiElement*>& elements) {
std::vector<const UiElement*> sorted_elements = elements;
std::stable_sort(sorted_elements.begin(), sorted_elements.end(),
[](const UiElement* first, const UiElement* second) {
return first->draw_phase() < second->draw_phase();
});
return sorted_elements;
}
}