blob: dac6519cd2dd1048435fa9150958e40c73abbd31 [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 "ash/fast_ink/fast_ink_view.h"
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2extchromium.h>
#include <memory>
#include "base/bind.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/views/widget/widget.h"
namespace fast_ink {
FastInkView::FastInkView(
aura::Window* container,
const FastInkHost::PresentationCallback& presentation_callback) {
widget_.reset(new views::Widget);
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
params.name = "FastInkOverlay";
params.accept_events = false;
params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
params.parent = container;
params.layer_type = ui::LAYER_SOLID_COLOR;
aura::Window* root_window = container->GetRootWindow();
gfx::Rect screen_bounds = root_window->GetBoundsInScreen();
widget_->Init(std::move(params));
widget_->Show();
widget_->SetContentsView(this);
widget_->SetBounds(screen_bounds);
set_owned_by_client();
host_ = std::make_unique<FastInkHost>(widget_->GetNativeWindow(),
std::move(presentation_callback));
}
FastInkView::ScopedPaint::ScopedPaint(FastInkView* view,
const gfx::Rect& damage_rect_in_window)
: gpu_memory_buffer_(view->host()->gpu_memory_buffer()),
damage_rect_(FastInkHost::BufferRectFromWindowRect(
view->host()->window_to_buffer_transform(),
gpu_memory_buffer_->GetSize(),
damage_rect_in_window)),
canvas_(damage_rect_.size(), 1.0f, false) {
canvas_.Translate(-damage_rect_.OffsetFromOrigin());
canvas_.Transform(view->host()->window_to_buffer_transform());
}
FastInkView::ScopedPaint::~ScopedPaint() {
if (damage_rect_.IsEmpty())
return;
{
TRACE_EVENT0("ui", "FastInkView::ScopedPaint::Map");
if (!gpu_memory_buffer_->Map()) {
LOG(ERROR) << "Failed to map GPU memory buffer";
return;
}
}
// Copy result to GPU memory buffer. This is effectively a memcpy and unlike
// drawing to the buffer directly this ensures that the buffer is never in a
// state that would result in flicker.
{
TRACE_EVENT1("ui", "FastInkView::ScopedPaint::Copy", "damage_rect",
damage_rect_.ToString());
uint8_t* data = static_cast<uint8_t*>(gpu_memory_buffer_->memory(0));
int stride = gpu_memory_buffer_->stride(0);
canvas_.GetBitmap().readPixels(
SkImageInfo::MakeN32Premul(damage_rect_.width(), damage_rect_.height()),
data + damage_rect_.y() * stride + damage_rect_.x() * 4, stride, 0, 0);
}
{
TRACE_EVENT0("ui", "FastInkView::UpdateBuffer::Unmap");
// Unmap to flush writes to buffer.
gpu_memory_buffer_->Unmap();
}
}
FastInkView::~FastInkView() = default;
void FastInkView::UpdateSurface(const gfx::Rect& content_rect,
const gfx::Rect& damage_rect,
bool auto_refresh) {
host_->UpdateSurface(content_rect, damage_rect, auto_refresh);
}
} // namespace fast_ink