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/base/util.h" | |
8 | |
9 namespace { | |
10 | |
11 const int kColorRingsCount = 4; | |
12 const int kFeedbackTexturePixelDiameter = 512; | |
13 const int kFeedbackTexturePixelRadius = kFeedbackTexturePixelDiameter / 2; | |
14 | |
15 // RGBA8888 colors. From inside to outside. | |
16 const uint8_t kFeedbackRingColors[kColorRingsCount] | |
17 [remoting::kBytesPerPixelRGB32] = { | |
18 {0, 0, 0, 0}, // transparent black | |
19 {0xff, 0xff, 0xff, 0xff}, // white | |
20 {0, 0, 0, 0xff}, // black | |
21 {0, 0, 0, 0} // transparent black | |
22 }; | |
23 | |
24 const float kFeedbackRadiusStops[kColorRingsCount] = {0.0f, 0.8f, 0.9f, 1.0f}; | |
25 | |
26 } // namespace | |
27 | |
28 namespace remoting { | |
29 | |
30 void LinearInterpolate(const uint8_t* in1, | |
31 const uint8_t* in2, | |
32 uint8_t* out, | |
33 int percentage, | |
34 int current_dimension) { | |
35 out[current_dimension] = (in1[current_dimension] * (100 - percentage) + | |
36 in2[current_dimension] * percentage) / 100; | |
37 } | |
38 | |
39 void FillColorByRadius(float radius, uint32_t* out) { | |
40 int i; | |
41 // Find first radius stop that is not smaller than current radius. | |
42 for (i = kColorRingsCount - 1; radius < kFeedbackRadiusStops[i] && i >= 0; | |
43 i--) { | |
44 } | |
45 | |
46 if (i < 0) { | |
47 NOTREACHED(); | |
48 return; | |
49 } | |
50 | |
51 if (i == kColorRingsCount - 1) { | |
52 // Area outside the circle. Just use the outermost color. | |
53 *out = *reinterpret_cast<const uint32_t*>(kFeedbackRingColors[i]); | |
54 return; | |
55 } | |
56 | |
57 const uint8_t* first_color = kFeedbackRingColors[i]; | |
58 const uint8_t* second_color = kFeedbackRingColors[i + 1]; | |
59 float first_radius = kFeedbackRadiusStops[i]; | |
60 float second_radius = kFeedbackRadiusStops[i + 1]; | |
61 | |
62 int percentage = | |
63 (radius - first_radius) * 100 / (second_radius - first_radius); | |
64 uint8_t* byte_out = reinterpret_cast<uint8_t*>(out); | |
65 LinearInterpolate(first_color, second_color, byte_out, percentage, 0); | |
66 LinearInterpolate(first_color, second_color, byte_out, percentage, 1); | |
67 LinearInterpolate(first_color, second_color, byte_out, percentage, 2); | |
68 LinearInterpolate(first_color, second_color, byte_out, percentage, 3); | |
69 } | |
70 | |
71 void FillColorMapping(uint32_t* map) { | |
72 for (int x = 0; x < kFeedbackTexturePixelRadius; x++) { | |
73 for (int y = 0; y <= x; y++) { | |
74 float radius = | |
75 sqrt(x * x + y * y) / kFeedbackTexturePixelRadius; | |
76 FillColorByRadius(radius, map + x + y * kFeedbackTexturePixelRadius); | |
77 } | |
78 } | |
79 } | |
80 | |
81 void FillFeedbackTexture(uint32_t* texture) { | |
82 // Color: RGBA8888. Equivalent to the upper part of the forth quadrant. | |
83 std::unique_ptr<uint32_t[]> coord_color_map( | |
84 new uint32_t[kFeedbackTexturePixelRadius * kFeedbackTexturePixelRadius]); | |
Yuwei
2016/07/20 22:56:48
After the change, it takes about 3ms to generate t
| |
85 | |
86 FillColorMapping(coord_color_map.get()); | |
87 | |
88 for (int x = 0; x < kFeedbackTexturePixelDiameter; x++) { | |
89 for (int y = 0; y < kFeedbackTexturePixelDiameter; y++) { | |
90 int mapped_x = abs(x - kFeedbackTexturePixelRadius); | |
91 int mapped_y = abs(y - kFeedbackTexturePixelRadius); | |
92 if (mapped_x < mapped_y) { | |
93 int temp_x = mapped_x; | |
94 mapped_x = mapped_y; | |
95 mapped_y = temp_x; | |
96 } | |
97 texture[x + y * kFeedbackTexturePixelDiameter] = | |
98 coord_color_map[mapped_x + mapped_y * kFeedbackTexturePixelRadius]; | |
99 } | |
100 } | |
101 } | |
102 | |
103 GlCursorFeedbackTexture* GlCursorFeedbackTexture::GetInstance() { | |
104 return base::Singleton<GlCursorFeedbackTexture>::get(); | |
105 } | |
106 | |
107 const uint8_t* GlCursorFeedbackTexture::GetTexture() const { | |
108 return reinterpret_cast<uint8_t*>(texture_.get()); | |
109 } | |
110 | |
111 int GlCursorFeedbackTexture::GetTextureDiameter() const { | |
112 return kFeedbackTexturePixelDiameter; | |
113 } | |
114 | |
115 GlCursorFeedbackTexture::GlCursorFeedbackTexture() : | |
116 texture_(new uint32_t[kFeedbackTexturePixelDiameter * | |
117 kFeedbackTexturePixelDiameter]) { | |
118 FillFeedbackTexture(texture_.get()); | |
119 } | |
120 | |
121 GlCursorFeedbackTexture::~GlCursorFeedbackTexture() { | |
122 } | |
123 | |
124 } // namespace remoting | |
OLD | NEW |