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