OLD | NEW |
| (Empty) |
1 // 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 | |
5 #include "remoting/client/gl_cursor_feedback_texture.h" | |
6 | |
7 #include "remoting/client/gl_render_layer.h" | |
8 | |
9 namespace remoting { | |
10 | |
11 namespace { | |
12 | |
13 const int kColorRingsCount = 5; | |
14 const int kFeedbackTexturePixelDiameter = 512; | |
15 const int kFeedbackTexturePixelRadius = kFeedbackTexturePixelDiameter / 2; | |
16 | |
17 // RGBA8888 colors. From inside to outside. | |
18 const uint8_t kFeedbackRingColors[kColorRingsCount] | |
19 [GlRenderLayer::kBytesPerPixel] = { | |
20 {0x0, 0x0, 0x0, 0x7f}, // Black | |
21 {0x0, 0x0, 0x0, 0x7f}, // Black | |
22 {0xff, 0xff, 0xff, 0x7f}, // White | |
23 {0xff, 0xff, 0xff, 0x7f}, // White | |
24 {0xff, 0xff, 0xff, 0} // Transparent White | |
25 }; | |
26 | |
27 const float kFeedbackRadiusStops[kColorRingsCount] = | |
28 {0.0f, 0.85f, 0.9f, 0.95f, 1.0f}; | |
29 | |
30 uint32_t GetColorByRadius(float radius) { | |
31 int ring_index = kColorRingsCount - 1; | |
32 // Find first radius stop that is not smaller than current radius. | |
33 while (radius < kFeedbackRadiusStops[ring_index] && ring_index >= 0) { | |
34 ring_index--; | |
35 } | |
36 | |
37 if (ring_index < 0) { | |
38 NOTREACHED(); | |
39 return 0; | |
40 } | |
41 | |
42 if (ring_index == kColorRingsCount - 1) { | |
43 // Area outside the circle. Just use the outermost color. | |
44 return *reinterpret_cast<const uint32_t*>(kFeedbackRingColors[ring_index]); | |
45 } | |
46 | |
47 const uint8_t* first_color = kFeedbackRingColors[ring_index]; | |
48 const uint8_t* second_color = kFeedbackRingColors[ring_index + 1]; | |
49 float first_radius = kFeedbackRadiusStops[ring_index]; | |
50 float second_radius = kFeedbackRadiusStops[ring_index + 1]; | |
51 | |
52 uint8_t progress = | |
53 (radius - first_radius) * 256 / (second_radius - first_radius); | |
54 uint32_t color; | |
55 uint8_t* color_ptr = reinterpret_cast<uint8_t*>(&color); | |
56 for (int i = 0; i < GlRenderLayer::kBytesPerPixel; i++) { | |
57 color_ptr[i] = | |
58 (first_color[i] * (256 - progress) + second_color[i] * progress) / 256; | |
59 } | |
60 return color; | |
61 } | |
62 | |
63 void FillFeedbackTexture(uint32_t* texture) { | |
64 for (int x = 0; x < kFeedbackTexturePixelRadius; x++) { | |
65 for (int y = 0; y <= x; y++) { | |
66 float radius = sqrt(x * x + y * y) / kFeedbackTexturePixelRadius; | |
67 uint32_t color = GetColorByRadius(radius); | |
68 | |
69 int x1 = kFeedbackTexturePixelRadius + x; | |
70 int x2 = kFeedbackTexturePixelRadius - 1 - x; | |
71 | |
72 int y1 = kFeedbackTexturePixelRadius + y; | |
73 int y2 = kFeedbackTexturePixelRadius - 1 - y; | |
74 | |
75 texture[x1 + y1 * kFeedbackTexturePixelDiameter] = color; | |
76 texture[x1 + y2 * kFeedbackTexturePixelDiameter] = color; | |
77 texture[x2 + y1 * kFeedbackTexturePixelDiameter] = color; | |
78 texture[x2 + y2 * kFeedbackTexturePixelDiameter] = color; | |
79 texture[y1 + x1 * kFeedbackTexturePixelDiameter] = color; | |
80 texture[y1 + x2 * kFeedbackTexturePixelDiameter] = color; | |
81 texture[y2 + x1 * kFeedbackTexturePixelDiameter] = color; | |
82 texture[y2 + x2 * kFeedbackTexturePixelDiameter] = color; | |
83 } | |
84 } | |
85 } | |
86 | |
87 } // namespace | |
88 | |
89 // static | |
90 const int GlCursorFeedbackTexture::kTextureWidth = | |
91 kFeedbackTexturePixelDiameter; | |
92 | |
93 GlCursorFeedbackTexture* GlCursorFeedbackTexture::GetInstance() { | |
94 return base::Singleton<GlCursorFeedbackTexture>::get(); | |
95 } | |
96 | |
97 const std::vector<uint8_t>& GlCursorFeedbackTexture::GetTexture() const { | |
98 return texture_; | |
99 } | |
100 | |
101 GlCursorFeedbackTexture::GlCursorFeedbackTexture() { | |
102 texture_.resize(kTextureWidth * kTextureWidth * | |
103 GlRenderLayer::kBytesPerPixel); | |
104 FillFeedbackTexture(reinterpret_cast<uint32_t*>(texture_.data())); | |
105 } | |
106 | |
107 GlCursorFeedbackTexture::~GlCursorFeedbackTexture() {} | |
108 | |
109 } // namespace remoting | |
OLD | NEW |