blob: 3dad73a1f557c35fdf5ef9cef09025f21739da16 [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
Jeremy Roman7c5cfabd2019-08-12 15:45:2721GlCursor::GlCursor() {}
yuweih2495ff02016-07-21 23:38:0322
joedow4d4db582017-05-15 18:34:5023GlCursor::~GlCursor() {
24 DCHECK(thread_checker_.CalledOnValidThread());
25}
yuweih2495ff02016-07-21 23:38:0326
27void GlCursor::SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) {
28 int data_size = cursor_shape.width() * cursor_shape.height() *
nicholss9949f5b2017-01-05 19:29:1729 GlRenderLayer::kBytesPerPixel;
yuweih2495ff02016-07-21 23:38:0330 if (current_cursor_data_size_ < data_size) {
31 current_cursor_data_size_ =
32 kDefaultCursorDataSize > data_size ? kDefaultCursorDataSize : data_size;
33 current_cursor_data_.reset(new uint8_t[current_cursor_data_size_]);
34 }
35 int stride = cursor_shape.width() * GlRenderLayer::kBytesPerPixel;
36 libyuv::ABGRToARGB(
37 reinterpret_cast<const uint8_t*>(cursor_shape.data().data()), stride,
38 current_cursor_data_.get(), stride, cursor_shape.width(),
39 cursor_shape.height());
40
41 bool size_changed = current_cursor_width_ != cursor_shape.width() ||
42 current_cursor_height_ != cursor_shape.height();
43
44 current_cursor_width_ = cursor_shape.width();
45 current_cursor_height_ = cursor_shape.height();
46 current_cursor_hotspot_x_ = cursor_shape.hotspot_x();
47 current_cursor_hotspot_y_ = cursor_shape.hotspot_y();
48
49 SetCurrentCursorShape(size_changed);
50
51 SetCursorPosition(cursor_x_, cursor_y_);
52}
53
yuweihb70334d2016-08-18 19:23:1554void GlCursor::SetCursorPosition(float x, float y) {
yuweih2495ff02016-07-21 23:38:0355 cursor_x_ = x;
56 cursor_y_ = y;
yuweih8d1912fd2016-08-08 21:26:5157 if (!current_cursor_data_) {
yuweih2495ff02016-07-21 23:38:0358 return;
59 }
60 std::array<float, 8> positions;
61 FillRectangleVertexPositions(
yuweih8d1912fd2016-08-08 21:26:5162 x - current_cursor_hotspot_x_, y - current_cursor_hotspot_y_,
63 current_cursor_width_, current_cursor_height_, &positions);
yuweih2495ff02016-07-21 23:38:0364 if (layer_) {
65 layer_->SetVertexPositions(positions);
66 }
67}
68
69void GlCursor::SetCursorVisible(bool visible) {
70 visible_ = visible;
71}
72
nicholssf62cc8a2017-01-12 16:08:4173void GlCursor::SetCanvas(base::WeakPtr<Canvas> canvas) {
yuweih2495ff02016-07-21 23:38:0374 if (!canvas) {
75 layer_.reset();
76 return;
77 }
yuweihcf627b982016-08-09 22:13:2578 layer_.reset(new GlRenderLayer(kGlCursorTextureId, canvas));
yuweih2495ff02016-07-21 23:38:0379 if (current_cursor_data_) {
80 SetCurrentCursorShape(true);
81 }
82 SetCursorPosition(cursor_x_, cursor_y_);
83}
84
nicholssf62cc8a2017-01-12 16:08:4185bool GlCursor::Draw() {
86 DCHECK(thread_checker_.CalledOnValidThread());
yuweih2495ff02016-07-21 23:38:0387 if (layer_ && current_cursor_data_ && visible_) {
88 layer_->Draw(1.f);
89 }
nicholssf62cc8a2017-01-12 16:08:4190 return false;
91}
92
93int GlCursor::GetZIndex() {
94 return Drawable::ZIndex::CURSOR;
yuweih2495ff02016-07-21 23:38:0395}
96
97void GlCursor::SetCurrentCursorShape(bool size_changed) {
98 if (layer_) {
99 if (size_changed) {
100 layer_->SetTexture(current_cursor_data_.get(), current_cursor_width_,
yuweihcf627b982016-08-09 22:13:25101 current_cursor_height_, 0);
yuweih2495ff02016-07-21 23:38:03102 } else {
103 layer_->UpdateTexture(current_cursor_data_.get(), 0, 0,
104 current_cursor_width_, current_cursor_width_, 0);
105 }
106 }
107}
108
nicholssf62cc8a2017-01-12 16:08:41109base::WeakPtr<Drawable> GlCursor::GetWeakPtr() {
110 DCHECK(thread_checker_.CalledOnValidThread());
111 return weak_factory_.GetWeakPtr();
112}
113
yuweih2495ff02016-07-21 23:38:03114} // namespace remoting