| Index: apps/moterm/moterm_view.cc
|
| diff --git a/apps/moterm/moterm_view.cc b/apps/moterm/moterm_view.cc
|
| index 838b817b7ac0fed875f4cc147572c02ee3f28a4c..4f992cc983e5fafbecb2a80e6306767de7729293 100644
|
| --- a/apps/moterm/moterm_view.cc
|
| +++ b/apps/moterm/moterm_view.cc
|
| @@ -15,14 +15,14 @@
|
| #include <string>
|
|
|
| #include "apps/moterm/key_util.h"
|
| +#include "base/bind.h"
|
| #include "base/logging.h"
|
| +#include "mojo/public/cpp/application/connect.h"
|
| #include "mojo/public/cpp/bindings/interface_request.h"
|
| #include "mojo/services/files/interfaces/file.mojom.h"
|
| #include "mojo/services/files/interfaces/types.mojom.h"
|
| -#include "mojo/services/input_events/interfaces/input_event_constants.mojom.h"
|
| -#include "mojo/services/input_events/interfaces/input_events.mojom.h"
|
| #include "mojo/services/terminal/interfaces/terminal_client.mojom.h"
|
| -#include "skia/ext/refptr.h"
|
| +#include "mojo/skia/ganesh_texture_surface.h"
|
| #include "third_party/dejavu-fonts-ttf-2.34/kDejaVuSansMonoRegular.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| #include "third_party/skia/include/core/SkCanvas.h"
|
| @@ -33,32 +33,17 @@
|
| #include "third_party/skia/include/core/SkStream.h"
|
| #include "third_party/skia/include/core/SkXfermode.h"
|
|
|
| -namespace {
|
| -
|
| -const GLint kTextureFormat =
|
| - (kN32_SkColorType == kRGBA_8888_SkColorType) ? GL_RGBA : GL_BGRA_EXT;
|
| -
|
| -mojo::Size RectToSize(const mojo::Rect& rect) {
|
| - mojo::Size size;
|
| - size.width = rect.width;
|
| - size.height = rect.height;
|
| - return size;
|
| -}
|
| -
|
| -} // namespace
|
| +constexpr uint32_t kMotermImageResourceId = 1;
|
| +constexpr uint32_t kRootNodeId = mojo::gfx::composition::kSceneRootNodeId;
|
|
|
| MotermView::MotermView(
|
| - mojo::Shell* shell,
|
| - mojo::View* view,
|
| - mojo::InterfaceRequest<mojo::ServiceProvider> service_provider_request)
|
| - : view_(view),
|
| - gl_helper_(this,
|
| - shell,
|
| - kTextureFormat,
|
| - false,
|
| - RectToSize(view->bounds())),
|
| + mojo::ApplicationImpl* app_impl,
|
| + mojo::InterfaceRequest<mojo::ServiceProvider> service_provider_request,
|
| + const mojo::ui::ViewProvider::CreateViewCallback& create_view_callback)
|
| + : GaneshView(app_impl, "Moterm", create_view_callback),
|
| + choreographer_(scene(), this),
|
| + input_handler_(view_service_provider(), this),
|
| model_(MotermModel::Size(240, 160), MotermModel::Size(24, 80), this),
|
| - frame_pending_(false),
|
| force_next_draw_(false),
|
| ascent_(0),
|
| line_height_(0),
|
| @@ -89,11 +74,6 @@ MotermView::MotermView(
|
| // monospace.
|
| advance_width_ = static_cast<int>(ceilf(fg_paint.measureText("X", 1)));
|
| DCHECK_GT(advance_width_, 0);
|
| -
|
| - view_->AddObserver(this);
|
| -
|
| - // Force an initial draw.
|
| - Draw(true);
|
| }
|
|
|
| MotermView::~MotermView() {
|
| @@ -101,39 +81,27 @@ MotermView::~MotermView() {
|
| driver_->Detach();
|
| }
|
|
|
| -void MotermView::OnViewDestroyed(mojo::View* view) {
|
| - DCHECK_EQ(view, view_);
|
| - view_->RemoveObserver(this);
|
| - delete this;
|
| -}
|
| -
|
| -void MotermView::OnViewBoundsChanged(mojo::View* view,
|
| - const mojo::Rect& old_bounds,
|
| - const mojo::Rect& new_bounds) {
|
| - DCHECK_EQ(view, view_);
|
| - gl_helper_.SetSurfaceSize(RectToSize(view_->bounds()));
|
| - bitmap_device_.clear();
|
| - Draw(true);
|
| -}
|
| +void MotermView::OnLayout(mojo::ui::ViewLayoutParamsPtr layout_params,
|
| + mojo::Array<uint32_t> children_needing_layout,
|
| + const OnLayoutCallback& callback) {
|
| + view_size_.width = layout_params->constraints->max_width;
|
| + view_size_.height = layout_params->constraints->max_height;
|
|
|
| -void MotermView::OnViewInputEvent(mojo::View* view,
|
| - const mojo::EventPtr& event) {
|
| - if (event->action == mojo::EventType::KEY_PRESSED)
|
| - OnKeyPressed(event);
|
| -}
|
| -
|
| -void MotermView::OnSurfaceIdChanged(mojo::SurfaceIdPtr surface_id) {
|
| - view_->SetSurfaceId(surface_id.Pass());
|
| -}
|
| + ScheduleDraw(true);
|
|
|
| -void MotermView::OnContextLost() {
|
| - // TODO(vtl): We'll need to force a draw when we regain a context.
|
| + auto info = mojo::ui::ViewLayoutResult::New();
|
| + info->size = view_size_.Clone();
|
| + callback.Run(info.Pass());
|
| }
|
|
|
| -void MotermView::OnFrameDisplayed(uint32_t frame_id) {
|
| - DCHECK(frame_pending_);
|
| - frame_pending_ = false;
|
| - Draw(false);
|
| +void MotermView::OnEvent(mojo::EventPtr event,
|
| + const OnEventCallback& callback) {
|
| + if (event->action == mojo::EventType::KEY_PRESSED) {
|
| + OnKeyPressed(event.Pass());
|
| + callback.Run(true);
|
| + } else {
|
| + callback.Run(false);
|
| + }
|
| }
|
|
|
| void MotermView::OnResponse(const void* buf, size_t size) {
|
| @@ -147,7 +115,7 @@ void MotermView::OnSetKeypadMode(bool application_mode) {
|
|
|
| void MotermView::OnDataReceived(const void* bytes, size_t num_bytes) {
|
| model_.ProcessInput(bytes, num_bytes, &model_state_changes_);
|
| - Draw(false);
|
| + ScheduleDraw(false);
|
| }
|
|
|
| void MotermView::OnClosed() {
|
| @@ -225,51 +193,65 @@ void MotermView::SetSize(uint32_t rows,
|
| bool reset,
|
| const SetSizeCallback& callback) {
|
| if (!rows) {
|
| - rows = std::max(1u, std::min(MotermModel::kMaxRows,
|
| - static_cast<uint32_t>(view_->bounds().height) /
|
| - line_height_));
|
| + rows = std::max(
|
| + 1u, std::min(MotermModel::kMaxRows,
|
| + static_cast<uint32_t>(view_size_.height) / line_height_));
|
| }
|
| if (!columns) {
|
| - columns =
|
| - std::max(1u, std::min(MotermModel::kMaxColumns,
|
| - static_cast<uint32_t>(view_->bounds().width) /
|
| - advance_width_));
|
| + columns = std::max(
|
| + 1u, std::min(MotermModel::kMaxColumns,
|
| + static_cast<uint32_t>(view_size_.width) / advance_width_));
|
| }
|
|
|
| model_.SetSize(MotermModel::Size(rows, columns), reset);
|
| callback.Run(mojo::files::Error::OK, rows, columns);
|
|
|
| - Draw(false);
|
| + ScheduleDraw(false);
|
| }
|
|
|
| -void MotermView::Draw(bool force) {
|
| - // TODO(vtl): See TODO above |frame_pending_| in the class declaration.
|
| - if (frame_pending_) {
|
| +void MotermView::ScheduleDraw(bool force) {
|
| + if (view_size_.width == 0 || view_size_.height == 0 ||
|
| + (!model_state_changes_.IsDirty() && !force && !force_next_draw_)) {
|
| force_next_draw_ |= force;
|
| return;
|
| }
|
| -
|
| - force |= force_next_draw_;
|
| force_next_draw_ = false;
|
| + choreographer_.ScheduleDraw();
|
| +}
|
|
|
| - if (!force && !model_state_changes_.IsDirty())
|
| - return;
|
| -
|
| - // TODO(vtl): If |!force|, draw only the dirty region(s)?
|
| +void MotermView::OnDraw(const mojo::gfx::composition::FrameInfo& frame_info,
|
| + const base::TimeDelta& time_delta) {
|
| + // TODO(vtl): Draw only the dirty region(s)?
|
| model_state_changes_.Reset();
|
|
|
| - int32_t width = view_->bounds().width;
|
| - int32_t height = view_->bounds().height;
|
| - DCHECK_GT(width, 0);
|
| - DCHECK_GT(height, 0);
|
| -
|
| - if (!bitmap_device_) {
|
| - bitmap_device_ = skia::AdoptRef(SkBitmapDevice::Create(SkImageInfo::Make(
|
| - width, height, kN32_SkColorType, kOpaque_SkAlphaType)));
|
| - }
|
| + mojo::Rect bounds;
|
| + bounds.width = view_size_.width;
|
| + bounds.height = view_size_.height;
|
| +
|
| + auto update = mojo::gfx::composition::SceneUpdate::New();
|
| + mojo::gfx::composition::ResourcePtr moterm_resource =
|
| + ganesh_renderer()->DrawCanvas(
|
| + view_size_,
|
| + base::Bind(&MotermView::DrawContent, base::Unretained(this)));
|
| + DCHECK(moterm_resource);
|
| + update->resources.insert(kMotermImageResourceId, moterm_resource.Pass());
|
| +
|
| + auto root_node = mojo::gfx::composition::Node::New();
|
| + root_node->op = mojo::gfx::composition::NodeOp::New();
|
| + root_node->op->set_image(mojo::gfx::composition::ImageNodeOp::New());
|
| + root_node->op->get_image()->content_rect = bounds.Clone();
|
| + root_node->op->get_image()->image_resource_id = kMotermImageResourceId;
|
| + update->nodes.insert(kRootNodeId, root_node.Pass());
|
| +
|
| + auto metadata = mojo::gfx::composition::SceneMetadata::New();
|
| + metadata->presentation_time = frame_info.presentation_time;
|
| +
|
| + scene()->Update(update.Pass());
|
| + scene()->Publish(metadata.Pass());
|
| +}
|
|
|
| - SkCanvas canvas(bitmap_device_.get());
|
| - canvas.clear(SK_ColorBLACK);
|
| +void MotermView::DrawContent(SkCanvas* canvas) {
|
| + canvas->clear(SK_ColorBLACK);
|
|
|
| SkPaint bg_paint;
|
| bg_paint.setStyle(SkPaint::kFill_Style);
|
| @@ -291,8 +273,8 @@ void MotermView::Draw(bool force) {
|
| bg_paint.setColor(SkColorSetRGB(ch.background_color.red,
|
| ch.background_color.green,
|
| ch.background_color.blue));
|
| - canvas.drawRect(SkRect::MakeXYWH(x, y, advance_width_, line_height_),
|
| - bg_paint);
|
| + canvas->drawRect(SkRect::MakeXYWH(x, y, advance_width_, line_height_),
|
| + bg_paint);
|
|
|
| // Paint the foreground.
|
| if (ch.code_point) {
|
| @@ -308,8 +290,8 @@ void MotermView::Draw(bool force) {
|
| ch.foreground_color.green,
|
| ch.foreground_color.blue));
|
|
|
| - canvas.drawText(&ch.code_point, sizeof(ch.code_point), x, y + ascent_,
|
| - fg_paint);
|
| + canvas->drawText(&ch.code_point, sizeof(ch.code_point), x, y + ascent_,
|
| + fg_paint);
|
| }
|
| }
|
| }
|
| @@ -324,27 +306,15 @@ void MotermView::Draw(bool force) {
|
| // focused and/or active.
|
| bg_paint.setColor(SK_ColorWHITE);
|
| bg_paint.setXfermodeMode(SkXfermode::kDifference_Mode);
|
| - canvas.drawRect(SkRect::MakeXYWH(cursor_pos.column * advance_width_,
|
| - cursor_pos.row * line_height_,
|
| - advance_width_, line_height_),
|
| - bg_paint);
|
| + canvas->drawRect(SkRect::MakeXYWH(cursor_pos.column * advance_width_,
|
| + cursor_pos.row * line_height_,
|
| + advance_width_, line_height_),
|
| + bg_paint);
|
| }
|
| -
|
| - canvas.flush();
|
| -
|
| - const SkBitmap& bitmap(bitmap_device_->accessBitmap(false));
|
| - // TODO(vtl): Do we need really need to lock/unlock pixels?
|
| - SkAutoLockPixels pixel_locker(bitmap);
|
| -
|
| - gl_helper_.StartFrame();
|
| - // (The texture is already bound.)
|
| - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, kTextureFormat,
|
| - GL_UNSIGNED_BYTE, bitmap.getPixels());
|
| - gl_helper_.EndFrame();
|
| - frame_pending_ = true;
|
| + canvas->flush();
|
| }
|
|
|
| -void MotermView::OnKeyPressed(const mojo::EventPtr& key_event) {
|
| +void MotermView::OnKeyPressed(mojo::EventPtr key_event) {
|
| std::string input_sequence =
|
| GetInputSequenceForKeyPressedEvent(*key_event, keypad_application_mode_);
|
| if (input_sequence.empty())
|
|
|