blob: 113de2566533260551eaa8a19fdf55053f091cd8 [file] [log] [blame]
yuweih2495ff02016-07-21 23:38:031// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
nicholss9949f5b2017-01-05 19:29:175#include "remoting/client/display/gl_cursor.h"
yuweih2495ff02016-07-21 23:38:036
7#include "remoting/base/util.h"
nicholss9949f5b2017-01-05 19:29:178#include "remoting/client/display/gl_canvas.h"
9#include "remoting/client/display/gl_math.h"
10#include "remoting/client/display/gl_render_layer.h"
11#include "remoting/client/display/gl_texture_ids.h"
yuweih2495ff02016-07-21 23:38:0312#include "remoting/proto/control.pb.h"
13#include "third_party/libyuv/include/libyuv/convert_argb.h"
14
15namespace remoting {
16
17namespace {
yuweih2495ff02016-07-21 23:38:0318const int kDefaultCursorDataSize = 32 * 32 * GlRenderLayer::kBytesPerPixel;
yuweih2495ff02016-07-21 23:38:0319} // namespace
20
nicholssf62cc8a2017-01-12 16:08:4121GlCursor::GlCursor() : weak_factory_(this) {}
yuweih2495ff02016-07-21 23:38:0322
23GlCursor::~GlCursor() {}
24
25void GlCursor::SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) {
26 int data_size = cursor_shape.width() * cursor_shape.height() *
nicholss9949f5b2017-01-05 19:29:1727 GlRenderLayer::kBytesPerPixel;
yuweih2495ff02016-07-21 23:38:0328 if (current_cursor_data_size_ < data_size) {
29 current_cursor_data_size_ =
30 kDefaultCursorDataSize > data_size ? kDefaultCursorDataSize : data_size;
31 current_cursor_data_.reset(new uint8_t[current_cursor_data_size_]);
32 }
33 int stride = cursor_shape.width() * GlRenderLayer::kBytesPerPixel;
34 libyuv::ABGRToARGB(
35 reinterpret_cast<const uint8_t*>(cursor_shape.data().data()), stride,
36 current_cursor_data_.get(), stride, cursor_shape.width(),
37 cursor_shape.height());
38
39 bool size_changed = current_cursor_width_ != cursor_shape.width() ||
40 current_cursor_height_ != cursor_shape.height();
41
42 current_cursor_width_ = cursor_shape.width();
43 current_cursor_height_ = cursor_shape.height();
44 current_cursor_hotspot_x_ = cursor_shape.hotspot_x();
45 current_cursor_hotspot_y_ = cursor_shape.hotspot_y();
46
47 SetCurrentCursorShape(size_changed);
48
49 SetCursorPosition(cursor_x_, cursor_y_);
50}
51
yuweihb70334d2016-08-18 19:23:1552void GlCursor::SetCursorPosition(float x, float y) {
yuweih2495ff02016-07-21 23:38:0353 cursor_x_ = x;
54 cursor_y_ = y;
yuweih8d1912fd2016-08-08 21:26:5155 if (!current_cursor_data_) {
yuweih2495ff02016-07-21 23:38:0356 return;
57 }
58 std::array<float, 8> positions;
59 FillRectangleVertexPositions(
yuweih8d1912fd2016-08-08 21:26:5160 x - current_cursor_hotspot_x_, y - current_cursor_hotspot_y_,
61 current_cursor_width_, current_cursor_height_, &positions);
yuweih2495ff02016-07-21 23:38:0362 if (layer_) {
63 layer_->SetVertexPositions(positions);
64 }
65}
66
67void GlCursor::SetCursorVisible(bool visible) {
68 visible_ = visible;
69}
70
nicholssf62cc8a2017-01-12 16:08:4171void GlCursor::SetCanvas(base::WeakPtr<Canvas> canvas) {
yuweih2495ff02016-07-21 23:38:0372 if (!canvas) {
73 layer_.reset();
74 return;
75 }
yuweihcf627b982016-08-09 22:13:2576 layer_.reset(new GlRenderLayer(kGlCursorTextureId, canvas));
yuweih2495ff02016-07-21 23:38:0377 if (current_cursor_data_) {
78 SetCurrentCursorShape(true);
79 }
80 SetCursorPosition(cursor_x_, cursor_y_);
81}
82
nicholssf62cc8a2017-01-12 16:08:4183bool GlCursor::Draw() {
84 DCHECK(thread_checker_.CalledOnValidThread());
yuweih2495ff02016-07-21 23:38:0385 if (layer_ && current_cursor_data_ && visible_) {
86 layer_->Draw(1.f);
87 }
nicholssf62cc8a2017-01-12 16:08:4188 return false;
89}
90
91int GlCursor::GetZIndex() {
92 return Drawable::ZIndex::CURSOR;
yuweih2495ff02016-07-21 23:38:0393}
94
95void GlCursor::SetCurrentCursorShape(bool size_changed) {
96 if (layer_) {
97 if (size_changed) {
98 layer_->SetTexture(current_cursor_data_.get(), current_cursor_width_,
yuweihcf627b982016-08-09 22:13:2599 current_cursor_height_, 0);
yuweih2495ff02016-07-21 23:38:03100 } else {
101 layer_->UpdateTexture(current_cursor_data_.get(), 0, 0,
102 current_cursor_width_, current_cursor_width_, 0);
103 }
104 }
105}
106
nicholssf62cc8a2017-01-12 16:08:41107base::WeakPtr<Drawable> GlCursor::GetWeakPtr() {
108 DCHECK(thread_checker_.CalledOnValidThread());
109 return weak_factory_.GetWeakPtr();
110}
111
yuweih2495ff02016-07-21 23:38:03112} // namespace remoting