Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(116)

Side by Side Diff: chrome/browser/android/vr_shell/vr_controller_model.cc

Issue 2837973002: VRShell: Composing Daydream controller textures from patches (Closed)
Patch Set: Separate patches and doing patching in CPU Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/vr_controller_model.h" 5 #include "chrome/browser/android/vr_shell/vr_controller_model.h"
6 6
7 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "chrome/browser/android/vr_shell/gltf_parser.h" 11 #include "chrome/browser/android/vr_shell/gltf_parser.h"
12 #include "components/component_updater/component_updater_paths.h" 12 #include "components/component_updater/component_updater_paths.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkRect.h"
15 #include "third_party/skia/include/core/SkSurface.h"
13 #include "ui/gfx/codec/png_codec.h" 16 #include "ui/gfx/codec/png_codec.h"
14 17
15 namespace vr_shell { 18 namespace vr_shell {
16 19
17 namespace { 20 namespace {
18 21
19 enum { 22 enum {
20 ELEMENTS_BUFFER_ID = 0, 23 ELEMENTS_BUFFER_ID = 0,
21 INDICES_BUFFER_ID = 1, 24 INDICES_BUFFER_ID = 1,
22 }; 25 };
23 26
24 constexpr char kPosition[] = "POSITION"; 27 constexpr char kPosition[] = "POSITION";
25 constexpr char kTexCoord[] = "TEXCOORD_0"; 28 constexpr char kTexCoord[] = "TEXCOORD_0";
26 29
30 // TODO(acondor): Remove these hardcoded paths once VrShell resources
31 // are delivered through component updater.
32 constexpr char const kComponentName[] = "VrShell";
33 constexpr char const kDefaultVersion[] = "0";
34
35 constexpr char const kModelsDirectory[] = "models";
36 constexpr char const kModelFilename[] = "controller.gltf";
37 constexpr char const kTexturesDirectory[] = "tex";
38 constexpr char const kBaseTextureFilename[] = "ddcontroller_idle.png";
39 constexpr char const* kTexturePatchesFilenames[] = {
40 "", "ddcontroller_touchpad.png", "ddcontroller_app.png",
41 "ddcontroller_system.png",
42 };
43 const gfx::Point kPatchesLocations[] = {{}, {5, 5}, {47, 165}, {47, 234}};
cjgrant 2017/04/27 18:47:29 How will you deliver these coordinates through com
acondor_ 2017/04/27 19:01:19 I'm in favor of delivering them in the component a
44
45 sk_sp<SkImage> LoadPNG(const base::FilePath& path) {
cjgrant 2017/04/27 18:47:29 nit: You're probably following the gfx::PNGCodec s
acondor_ 2017/04/27 19:01:19 Acknowledged.
acondor_ 2017/04/28 14:22:38 Done.
46 std::string data;
47 SkBitmap bitmap;
48 if (!base::ReadFileToString(path, &data) ||
49 !gfx::PNGCodec::Decode(
50 reinterpret_cast<const unsigned char*>(data.data()), data.size(),
51 &bitmap) ||
52 bitmap.colorType() != kRGBA_8888_SkColorType) {
53 return nullptr;
54 }
55 return SkImage::MakeFromBitmap(bitmap);
56 }
57
27 } // namespace 58 } // namespace
28 59
29 constexpr char const VrControllerModel::kComponentName[]; 60 VrControllerModel::Patch::Patch() = default;
30 constexpr char const VrControllerModel::kDefaultVersion[]; 61 VrControllerModel::Patch::Patch(sk_sp<SkImage> image, const gfx::Point& offset)
31 constexpr char const VrControllerModel::kModelsDirectory[]; 62 : image(image), offset(offset) {}
32 constexpr char const VrControllerModel::kModelFilename[]; 63 VrControllerModel::Patch::~Patch() = default;
33 constexpr char const VrControllerModel::kTexturesDirectory[];
34 constexpr char const* VrControllerModel::kTextureFilenames[];
35 64
36 VrControllerModel::VrControllerModel( 65 VrControllerModel::VrControllerModel(
37 std::unique_ptr<gltf::Asset> gltf_asset, 66 std::unique_ptr<gltf::Asset> gltf_asset,
38 std::vector<std::unique_ptr<gltf::Buffer>> buffers) 67 std::vector<std::unique_ptr<gltf::Buffer>> buffers)
39 : gltf_asset_(std::move(gltf_asset)), 68 : gltf_asset_(std::move(gltf_asset)),
40 texture_bitmaps_(State::STATE_COUNT),
41 buffers_(std::move(buffers)) {} 69 buffers_(std::move(buffers)) {}
42 70
43 VrControllerModel::~VrControllerModel() = default; 71 VrControllerModel::~VrControllerModel() = default;
44 72
45 const GLvoid* VrControllerModel::ElementsBuffer() const { 73 const GLvoid* VrControllerModel::ElementsBuffer() const {
46 const gltf::BufferView* buffer_view = 74 const gltf::BufferView* buffer_view =
47 gltf_asset_->GetBufferView(ELEMENTS_BUFFER_ID); 75 gltf_asset_->GetBufferView(ELEMENTS_BUFFER_ID);
48 DCHECK(buffer_view && buffer_view->target == GL_ARRAY_BUFFER); 76 DCHECK(buffer_view && buffer_view->target == GL_ARRAY_BUFFER);
49 const char* buffer = Buffer(); 77 const char* buffer = Buffer();
50 return buffer ? buffer + buffer_view->byte_offset : nullptr; 78 return buffer ? buffer + buffer_view->byte_offset : nullptr;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 113 }
86 114
87 const gltf::Accessor* VrControllerModel::PositionAccessor() const { 115 const gltf::Accessor* VrControllerModel::PositionAccessor() const {
88 return Accessor(kPosition); 116 return Accessor(kPosition);
89 } 117 }
90 118
91 const gltf::Accessor* VrControllerModel::TextureCoordinateAccessor() const { 119 const gltf::Accessor* VrControllerModel::TextureCoordinateAccessor() const {
92 return Accessor(kTexCoord); 120 return Accessor(kTexCoord);
93 } 121 }
94 122
95 void VrControllerModel::SetTexture(int state, 123 void VrControllerModel::SetBaseTexture(sk_sp<SkImage> image) {
96 std::unique_ptr<SkBitmap> bitmap) { 124 base_texture_ = image;
97 DCHECK(state >= 0 && state < STATE_COUNT);
98 texture_bitmaps_[state] = std::move(bitmap);
99 } 125 }
100 126
101 const SkBitmap* VrControllerModel::GetTexture(int state) const { 127 void VrControllerModel::SetTexturePatch(int state, sk_sp<SkImage> image) {
102 DCHECK(state >= 0 && state < STATE_COUNT); 128 DCHECK(state >= 0 && state < STATE_COUNT);
103 return texture_bitmaps_[state].get(); 129 patches_[state] = image;
130 }
131
132 sk_sp<SkImage> VrControllerModel::GetTexture(int state) const {
133 if (!patches_[state])
134 return base_texture_;
135 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
136 base_texture_->width(), base_texture_->height());
137 SkCanvas* canvas = surface->getCanvas();
138 canvas->drawImage(base_texture_, 0, 0);
139 SkPaint paint;
140 paint.setBlendMode(SkBlendMode::kSrc);
141 canvas->drawImage(patches_[state], kPatchesLocations[state].x(),
142 kPatchesLocations[state].y(), &paint);
143 return sk_sp<SkImage>(surface->makeImageSnapshot());
104 } 144 }
105 145
106 const char* VrControllerModel::Buffer() const { 146 const char* VrControllerModel::Buffer() const {
107 if (buffers_.empty()) 147 if (buffers_.empty())
108 return nullptr; 148 return nullptr;
109 return buffers_[0]->data(); 149 return buffers_[0]->data();
110 } 150 }
111 151
112 const gltf::Accessor* VrControllerModel::Accessor( 152 const gltf::Accessor* VrControllerModel::Accessor(
113 const std::string& key) const { 153 const std::string& key) const {
114 const gltf::Mesh* mesh = gltf_asset_->GetMesh(0); 154 const gltf::Mesh* mesh = gltf_asset_->GetMesh(0);
115 DCHECK(mesh && mesh->primitives.size()); 155 DCHECK(mesh && mesh->primitives.size());
116 auto it = mesh->primitives[0]->attributes.find(key); 156 auto it = mesh->primitives[0]->attributes.find(key);
117 DCHECK(it != mesh->primitives[0]->attributes.begin()); 157 DCHECK(it != mesh->primitives[0]->attributes.begin());
118 return it->second; 158 return it->second;
119 } 159 }
120 160
121 std::unique_ptr<VrControllerModel> VrControllerModel::LoadFromComponent() { 161 std::unique_ptr<VrControllerModel> VrControllerModel::LoadFromComponent() {
122 base::FilePath models_path; 162 base::FilePath models_path;
123 PathService::Get(component_updater::DIR_COMPONENT_USER, &models_path); 163 PathService::Get(component_updater::DIR_COMPONENT_USER, &models_path);
124 models_path = models_path.Append(VrControllerModel::kComponentName) 164 models_path = models_path.Append(kComponentName)
125 .Append(VrControllerModel::kDefaultVersion) 165 .Append(kDefaultVersion)
126 .Append(VrControllerModel::kModelsDirectory); 166 .Append(kModelsDirectory);
127 auto model_path = models_path.Append(VrControllerModel::kModelFilename); 167 auto model_path = models_path.Append(kModelFilename);
128 168
129 // No further action if model file is not present 169 // No further action if model file is not present
130 if (!base::PathExists(model_path)) { 170 if (!base::PathExists(model_path)) {
131 LOG(WARNING) << "Controller model files not found"; 171 LOG(WARNING) << "Controller model files not found";
132 return nullptr; 172 return nullptr;
133 } 173 }
134 174
135 GltfParser gltf_parser; 175 GltfParser gltf_parser;
136 std::vector<std::unique_ptr<gltf::Buffer>> buffers; 176 std::vector<std::unique_ptr<gltf::Buffer>> buffers;
137 auto asset = gltf_parser.Parse(model_path, &buffers); 177 auto asset = gltf_parser.Parse(model_path, &buffers);
138 if (!asset) { 178 if (!asset) {
139 LOG(ERROR) << "Failed to read controller model"; 179 LOG(ERROR) << "Failed to read controller model";
140 return nullptr; 180 return nullptr;
141 } 181 }
142 182
143 auto controller_model = 183 auto controller_model =
144 base::MakeUnique<VrControllerModel>(std::move(asset), std::move(buffers)); 184 base::MakeUnique<VrControllerModel>(std::move(asset), std::move(buffers));
145 185
146 auto textures_path = 186 auto textures_path = models_path.Append(kTexturesDirectory);
147 models_path.Append(VrControllerModel::kTexturesDirectory); 187
188 auto base_texture = LoadPNG(textures_path.Append(kBaseTextureFilename));
189 if (!base_texture) {
190 LOG(ERROR) << "Failed to read controller base texture";
191 return nullptr;
192 }
193 controller_model->SetBaseTexture(std::move(base_texture));
148 194
149 for (int i = 0; i < VrControllerModel::STATE_COUNT; i++) { 195 for (int i = 0; i < VrControllerModel::STATE_COUNT; i++) {
150 auto texture_path = 196 if (!kTexturePatchesFilenames[i][0])
151 textures_path.Append(VrControllerModel::kTextureFilenames[i]); 197 continue;
152 std::string data; 198 auto patch_image =
153 auto bitmap = base::MakeUnique<SkBitmap>(); 199 LoadPNG(textures_path.Append(kTexturePatchesFilenames[i]));
154 if (!base::ReadFileToString(texture_path, &data) || 200 if (!patch_image) {
155 !gfx::PNGCodec::Decode( 201 LOG(ERROR) << "Failed to read controller texture patch";
156 reinterpret_cast<const unsigned char*>(data.data()), data.size(), 202 continue;
cjgrant 2017/04/27 18:47:29 If this fails, do we want to feed back the failure
acondor_ 2017/04/27 19:01:19 There are only patches for clicked buttons, so it
157 bitmap.get()) ||
158 bitmap->colorType() != kRGBA_8888_SkColorType) {
159 LOG(ERROR) << "Failed to read controller texture";
160 return nullptr;
161 } 203 }
162 controller_model->SetTexture(i, std::move(bitmap)); 204 controller_model->SetTexturePatch(i, patch_image);
163 } 205 }
164 206
165 return controller_model; 207 return controller_model;
166 } 208 }
167 209
168 } // namespace vr_shell 210 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698