OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "gpu/command_buffer/service/texture_manager.h" | 5 #include "gpu/command_buffer/service/texture_manager.h" |
6 #include "base/bits.h" | 6 #include "base/bits.h" |
7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 7 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
8 #include "gpu/command_buffer/service/feature_info.h" | 8 #include "gpu/command_buffer/service/feature_info.h" |
9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 9 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
10 | 10 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 bool TextureManager::TextureInfo::MarkMipmapsGenerated( | 111 bool TextureManager::TextureInfo::MarkMipmapsGenerated( |
112 const FeatureInfo* feature_info) { | 112 const FeatureInfo* feature_info) { |
113 if (!CanGenerateMipmaps(feature_info)) { | 113 if (!CanGenerateMipmaps(feature_info)) { |
114 return false; | 114 return false; |
115 } | 115 } |
116 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 116 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
117 const TextureInfo::LevelInfo& info1 = level_infos_[ii][0]; | 117 const TextureInfo::LevelInfo& info1 = level_infos_[ii][0]; |
118 GLsizei width = info1.width; | 118 GLsizei width = info1.width; |
119 GLsizei height = info1.height; | 119 GLsizei height = info1.height; |
120 GLsizei depth = info1.depth; | 120 GLsizei depth = info1.depth; |
| 121 GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : |
| 122 FaceIndexToGLTarget(ii); |
121 int num_mips = ComputeMipMapCount(width, height, depth); | 123 int num_mips = ComputeMipMapCount(width, height, depth); |
122 for (int level = 1; level < num_mips; ++level) { | 124 for (int level = 1; level < num_mips; ++level) { |
123 width = std::max(1, width >> 1); | 125 width = std::max(1, width >> 1); |
124 height = std::max(1, height >> 1); | 126 height = std::max(1, height >> 1); |
125 depth = std::max(1, depth >> 1); | 127 depth = std::max(1, depth >> 1); |
126 SetLevelInfo(feature_info, | 128 SetLevelInfo(feature_info, |
127 target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : | 129 target, |
128 FaceIndexToGLTarget(ii), | |
129 level, | 130 level, |
130 info1.internal_format, | 131 info1.internal_format, |
131 width, | 132 width, |
132 height, | 133 height, |
133 depth, | 134 depth, |
134 info1.border, | 135 info1.border, |
135 info1.format, | 136 info1.format, |
136 info1.type); | 137 info1.type, |
| 138 true); |
137 } | 139 } |
138 } | 140 } |
| 141 |
139 return true; | 142 return true; |
140 } | 143 } |
141 | 144 |
142 void TextureManager::TextureInfo::SetTarget(GLenum target, GLint max_levels) { | 145 void TextureManager::TextureInfo::SetTarget(GLenum target, GLint max_levels) { |
143 DCHECK_EQ(0u, target_); // you can only set this once. | 146 DCHECK_EQ(0u, target_); // you can only set this once. |
144 target_ = target; | 147 target_ = target; |
145 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; | 148 size_t num_faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; |
146 level_infos_.resize(num_faces); | 149 level_infos_.resize(num_faces); |
147 for (size_t ii = 0; ii < num_faces; ++ii) { | 150 for (size_t ii = 0; ii < num_faces; ++ii) { |
148 level_infos_[ii].resize(max_levels); | 151 level_infos_[ii].resize(max_levels); |
149 } | 152 } |
150 | 153 |
151 if (target == GL_TEXTURE_EXTERNAL_OES) { | 154 if (target == GL_TEXTURE_EXTERNAL_OES) { |
152 min_filter_ = GL_LINEAR; | 155 min_filter_ = GL_LINEAR; |
153 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; | 156 wrap_s_ = wrap_t_ = GL_CLAMP_TO_EDGE; |
154 } | 157 } |
155 } | 158 } |
156 | 159 |
157 bool TextureManager::TextureInfo::CanGenerateMipmaps( | 160 bool TextureManager::TextureInfo::CanGenerateMipmaps( |
158 const FeatureInfo* feature_info) const { | 161 const FeatureInfo* feature_info) const { |
159 if ((npot() && !feature_info->feature_flags().npot_ok) || | 162 if ((npot() && !feature_info->feature_flags().npot_ok) || |
160 level_infos_.empty() || IsDeleted() || | 163 level_infos_.empty() || IsDeleted() || |
161 target_ == GL_TEXTURE_EXTERNAL_OES) { | 164 target_ == GL_TEXTURE_EXTERNAL_OES) { |
162 return false; | 165 return false; |
163 } | 166 } |
164 const TextureInfo::LevelInfo& first = level_infos_[0][0]; | 167 const TextureInfo::LevelInfo& first = level_infos_[0][0]; |
165 // TODO(gman): Check internal_format, format and type. | 168 // TODO(gman): Check internal_format, format and type. |
166 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 169 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
167 const LevelInfo& info = level_infos_[ii][0]; | 170 const LevelInfo& info = level_infos_[ii][0]; |
168 if ((!info.valid) || | 171 if ((info.target == 0) || |
169 (info.width != first.width) || | 172 (info.width != first.width) || |
170 (info.height != first.height) || | 173 (info.height != first.height) || |
171 (info.depth != 1) || | 174 (info.depth != 1) || |
172 (info.format != first.format) || | 175 (info.format != first.format) || |
173 (info.internal_format != first.internal_format) || | 176 (info.internal_format != first.internal_format) || |
174 (info.type != first.type)) { | 177 (info.type != first.type)) { |
175 return false; | 178 return false; |
176 } | 179 } |
177 } | 180 } |
178 return true; | 181 return true; |
179 } | 182 } |
180 | 183 |
| 184 void TextureManager::TextureInfo::SetLevelCleared(GLenum target, GLint level) { |
| 185 DCHECK_GE(level, 0); |
| 186 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), |
| 187 level_infos_.size()); |
| 188 DCHECK_LT(static_cast<size_t>(level), |
| 189 level_infos_[GLTargetToFaceIndex(target)].size()); |
| 190 TextureInfo::LevelInfo& info = |
| 191 level_infos_[GLTargetToFaceIndex(target)][level]; |
| 192 if (!info.cleared) { |
| 193 DCHECK_NE(0, num_uncleared_mips_); |
| 194 --num_uncleared_mips_; |
| 195 } |
| 196 info.cleared = true; |
| 197 UpdateCleared(); |
| 198 } |
| 199 |
| 200 void TextureManager::TextureInfo::UpdateCleared() { |
| 201 if (level_infos_.empty()) { |
| 202 return; |
| 203 } |
| 204 |
| 205 const TextureInfo::LevelInfo& first_face = level_infos_[0][0]; |
| 206 int levels_needed = ComputeMipMapCount( |
| 207 first_face.width, first_face.height, first_face.depth); |
| 208 cleared_ = true; |
| 209 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
| 210 for (GLint jj = 0; jj < levels_needed; ++jj) { |
| 211 const TextureInfo::LevelInfo& info = level_infos_[ii][jj]; |
| 212 if (info.width > 0 && info.height > 0 && info.depth > 0 && |
| 213 !info.cleared) { |
| 214 cleared_ = false; |
| 215 return; |
| 216 } |
| 217 } |
| 218 } |
| 219 } |
| 220 |
181 void TextureManager::TextureInfo::SetLevelInfo( | 221 void TextureManager::TextureInfo::SetLevelInfo( |
182 const FeatureInfo* feature_info, | 222 const FeatureInfo* feature_info, |
183 GLenum target, | 223 GLenum target, |
184 GLint level, | 224 GLint level, |
185 GLenum internal_format, | 225 GLenum internal_format, |
186 GLsizei width, | 226 GLsizei width, |
187 GLsizei height, | 227 GLsizei height, |
188 GLsizei depth, | 228 GLsizei depth, |
189 GLint border, | 229 GLint border, |
190 GLenum format, | 230 GLenum format, |
191 GLenum type) { | 231 GLenum type, |
| 232 bool cleared) { |
192 DCHECK_GE(level, 0); | 233 DCHECK_GE(level, 0); |
193 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), | 234 DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)), |
194 level_infos_.size()); | 235 level_infos_.size()); |
195 DCHECK_LT(static_cast<size_t>(level), | 236 DCHECK_LT(static_cast<size_t>(level), |
196 level_infos_[GLTargetToFaceIndex(target)].size()); | 237 level_infos_[GLTargetToFaceIndex(target)].size()); |
197 DCHECK_GE(width, 0); | 238 DCHECK_GE(width, 0); |
198 DCHECK_GE(height, 0); | 239 DCHECK_GE(height, 0); |
199 DCHECK_GE(depth, 0); | 240 DCHECK_GE(depth, 0); |
200 TextureInfo::LevelInfo& info = | 241 TextureInfo::LevelInfo& info = |
201 level_infos_[GLTargetToFaceIndex(target)][level]; | 242 level_infos_[GLTargetToFaceIndex(target)][level]; |
202 info.valid = true; | 243 info.target = target; |
| 244 info.level = level; |
203 info.internal_format = internal_format; | 245 info.internal_format = internal_format; |
204 info.width = width; | 246 info.width = width; |
205 info.height = height; | 247 info.height = height; |
206 info.depth = depth; | 248 info.depth = depth; |
207 info.border = border; | 249 info.border = border; |
208 info.format = format; | 250 info.format = format; |
209 info.type = type; | 251 info.type = type; |
| 252 if (!info.cleared) { |
| 253 DCHECK_NE(0, num_uncleared_mips_); |
| 254 --num_uncleared_mips_; |
| 255 } |
| 256 info.cleared = cleared; |
| 257 if (!info.cleared) { |
| 258 ++num_uncleared_mips_; |
| 259 } |
210 max_level_set_ = std::max(max_level_set_, level); | 260 max_level_set_ = std::max(max_level_set_, level); |
211 Update(feature_info); | 261 Update(feature_info); |
| 262 UpdateCleared(); |
212 } | 263 } |
213 | 264 |
214 bool TextureManager::TextureInfo::ValidForTexture( | 265 bool TextureManager::TextureInfo::ValidForTexture( |
215 GLint face, | 266 GLint face, |
216 GLint level, | 267 GLint level, |
217 GLint xoffset, | 268 GLint xoffset, |
218 GLint yoffset, | 269 GLint yoffset, |
219 GLsizei width, | 270 GLsizei width, |
220 GLsizei height, | 271 GLsizei height, |
221 GLenum format, | 272 GLenum format, |
(...skipping 17 matching lines...) Expand all Loading... |
239 } | 290 } |
240 | 291 |
241 bool TextureManager::TextureInfo::GetLevelSize( | 292 bool TextureManager::TextureInfo::GetLevelSize( |
242 GLint face, GLint level, GLsizei* width, GLsizei* height) const { | 293 GLint face, GLint level, GLsizei* width, GLsizei* height) const { |
243 DCHECK(width); | 294 DCHECK(width); |
244 DCHECK(height); | 295 DCHECK(height); |
245 size_t face_index = GLTargetToFaceIndex(face); | 296 size_t face_index = GLTargetToFaceIndex(face); |
246 if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() && | 297 if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() && |
247 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 298 static_cast<size_t>(level) < level_infos_[face_index].size()) { |
248 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level]; | 299 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level]; |
249 if (info.valid) { | 300 if (info.target != 0) { |
250 *width = info.width; | 301 *width = info.width; |
251 *height = info.height; | 302 *height = info.height; |
252 return true; | 303 return true; |
253 } | 304 } |
254 } | 305 } |
255 return false; | 306 return false; |
256 } | 307 } |
257 | 308 |
258 bool TextureManager::TextureInfo::GetLevelType( | 309 bool TextureManager::TextureInfo::GetLevelType( |
259 GLint face, GLint level, GLenum* type, GLenum* internal_format) const { | 310 GLint face, GLint level, GLenum* type, GLenum* internal_format) const { |
260 DCHECK(type); | 311 DCHECK(type); |
261 DCHECK(internal_format); | 312 DCHECK(internal_format); |
262 size_t face_index = GLTargetToFaceIndex(face); | 313 size_t face_index = GLTargetToFaceIndex(face); |
263 if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() && | 314 if (!IsDeleted() && level >= 0 && face_index < level_infos_.size() && |
264 static_cast<size_t>(level) < level_infos_[face_index].size()) { | 315 static_cast<size_t>(level) < level_infos_[face_index].size()) { |
265 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level]; | 316 const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level]; |
266 if (info.valid) { | 317 if (info.target != 0) { |
267 *type = info.type; | 318 *type = info.type; |
268 *internal_format = info.internal_format; | 319 *internal_format = info.internal_format; |
269 return true; | 320 return true; |
270 } | 321 } |
271 } | 322 } |
272 return false; | 323 return false; |
273 } | 324 } |
274 | 325 |
275 bool TextureManager::TextureInfo::SetParameter( | 326 bool TextureManager::TextureInfo::SetParameter( |
276 const FeatureInfo* feature_info, GLenum pname, GLint param) { | 327 const FeatureInfo* feature_info, GLenum pname, GLint param) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 wrap_t_ = param; | 362 wrap_t_ = param; |
312 break; | 363 break; |
313 case GL_TEXTURE_MAX_ANISOTROPY_EXT: | 364 case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
314 // Nothing to do for this case at the moment. | 365 // Nothing to do for this case at the moment. |
315 break; | 366 break; |
316 default: | 367 default: |
317 NOTREACHED(); | 368 NOTREACHED(); |
318 return false; | 369 return false; |
319 } | 370 } |
320 Update(feature_info); | 371 Update(feature_info); |
| 372 UpdateCleared(); |
321 return true; | 373 return true; |
322 } | 374 } |
323 | 375 |
324 void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) { | 376 void TextureManager::TextureInfo::Update(const FeatureInfo* feature_info) { |
325 // Update npot status. | 377 // Update npot status. |
326 npot_ = false; | 378 npot_ = false; |
327 | 379 |
328 if (level_infos_.empty()) { | 380 if (level_infos_.empty()) { |
329 texture_complete_ = false; | 381 texture_complete_ = false; |
330 cube_complete_ = false; | 382 cube_complete_ = false; |
331 return; | 383 return; |
332 } | 384 } |
333 | 385 |
| 386 // checks that the first mip of any face is npot. |
334 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { | 387 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
335 const TextureInfo::LevelInfo& info = level_infos_[ii][0]; | 388 const TextureInfo::LevelInfo& info = level_infos_[ii][0]; |
336 if (GLES2Util::IsNPOT(info.width) || | 389 if (GLES2Util::IsNPOT(info.width) || |
337 GLES2Util::IsNPOT(info.height) || | 390 GLES2Util::IsNPOT(info.height) || |
338 GLES2Util::IsNPOT(info.depth)) { | 391 GLES2Util::IsNPOT(info.depth)) { |
339 npot_ = true; | 392 npot_ = true; |
340 break; | 393 break; |
341 } | 394 } |
342 } | 395 } |
343 | 396 |
(...skipping 16 matching lines...) Expand all Loading... |
360 } else if (first_face.type == GL_HALF_FLOAT_OES && | 413 } else if (first_face.type == GL_HALF_FLOAT_OES && |
361 !feature_info->feature_flags().enable_texture_half_float_linear && | 414 !feature_info->feature_flags().enable_texture_half_float_linear && |
362 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || | 415 (min_filter_ != GL_NEAREST_MIPMAP_NEAREST || |
363 mag_filter_ != GL_NEAREST)) { | 416 mag_filter_ != GL_NEAREST)) { |
364 texture_complete_ = false; | 417 texture_complete_ = false; |
365 } | 418 } |
366 for (size_t ii = 0; | 419 for (size_t ii = 0; |
367 ii < level_infos_.size() && (cube_complete_ || texture_complete_); | 420 ii < level_infos_.size() && (cube_complete_ || texture_complete_); |
368 ++ii) { | 421 ++ii) { |
369 const TextureInfo::LevelInfo& level0 = level_infos_[ii][0]; | 422 const TextureInfo::LevelInfo& level0 = level_infos_[ii][0]; |
370 if (!level0.valid || | 423 if (level0.target == 0 || |
371 level0.width != first_face.width || | 424 level0.width != first_face.width || |
372 level0.height != first_face.height || | 425 level0.height != first_face.height || |
373 level0.depth != 1 || | 426 level0.depth != 1 || |
374 level0.internal_format != first_face.internal_format || | 427 level0.internal_format != first_face.internal_format || |
375 level0.format != first_face.format || | 428 level0.format != first_face.format || |
376 level0.type != first_face.type) { | 429 level0.type != first_face.type) { |
377 cube_complete_ = false; | 430 cube_complete_ = false; |
378 } | 431 } |
379 // Get level0 dimensions | 432 // Get level0 dimensions |
380 GLsizei width = level0.width; | 433 GLsizei width = level0.width; |
381 GLsizei height = level0.height; | 434 GLsizei height = level0.height; |
382 GLsizei depth = level0.depth; | 435 GLsizei depth = level0.depth; |
383 for (GLint jj = 1; jj < levels_needed; ++jj) { | 436 for (GLint jj = 1; jj < levels_needed; ++jj) { |
384 // compute required size for mip. | 437 // compute required size for mip. |
385 width = std::max(1, width >> 1); | 438 width = std::max(1, width >> 1); |
386 height = std::max(1, height >> 1); | 439 height = std::max(1, height >> 1); |
387 depth = std::max(1, depth >> 1); | 440 depth = std::max(1, depth >> 1); |
388 const TextureInfo::LevelInfo& info = level_infos_[ii][jj]; | 441 const TextureInfo::LevelInfo& info = level_infos_[ii][jj]; |
389 if (!info.valid || | 442 if (info.target == 0 || |
390 info.width != width || | 443 info.width != width || |
391 info.height != height || | 444 info.height != height || |
392 info.depth != depth || | 445 info.depth != depth || |
393 info.internal_format != level0.internal_format || | 446 info.internal_format != level0.internal_format || |
394 info.format != level0.format || | 447 info.format != level0.format || |
395 info.type != level0.type) { | 448 info.type != level0.type) { |
396 texture_complete_ = false; | 449 texture_complete_ = false; |
397 break; | 450 break; |
398 } | 451 } |
399 } | 452 } |
400 } | 453 } |
401 } | 454 } |
402 | 455 |
| 456 bool TextureManager::TextureInfo::ClearRenderableLevels(GLES2Decoder* decoder) { |
| 457 DCHECK(decoder); |
| 458 if (SafeToRenderFrom()) { |
| 459 return true; |
| 460 } |
| 461 |
| 462 const TextureInfo::LevelInfo& first_face = level_infos_[0][0]; |
| 463 int levels_needed = ComputeMipMapCount( |
| 464 first_face.width, first_face.height, first_face.depth); |
| 465 |
| 466 for (size_t ii = 0; ii < level_infos_.size(); ++ii) { |
| 467 for (GLint jj = 0; jj < levels_needed; ++jj) { |
| 468 TextureInfo::LevelInfo& info = level_infos_[ii][jj]; |
| 469 if (info.target != 0) { |
| 470 if (!ClearLevel(decoder, info.target, jj)) { |
| 471 return false; |
| 472 } |
| 473 } |
| 474 } |
| 475 } |
| 476 cleared_ = true; |
| 477 return true; |
| 478 } |
| 479 |
| 480 bool TextureManager::TextureInfo::IsLevelCleared(GLenum target, GLint level) { |
| 481 size_t face_index = GLTargetToFaceIndex(target); |
| 482 if (IsDeleted() || |
| 483 face_index >= level_infos_.size() || |
| 484 level >= static_cast<GLint>(level_infos_[face_index].size())) { |
| 485 return true; |
| 486 } |
| 487 |
| 488 TextureInfo::LevelInfo& info = level_infos_[face_index][level]; |
| 489 |
| 490 return info.cleared; |
| 491 } |
| 492 |
| 493 bool TextureManager::TextureInfo::ClearLevel( |
| 494 GLES2Decoder* decoder, GLenum target, GLint level) { |
| 495 DCHECK(decoder); |
| 496 size_t face_index = GLTargetToFaceIndex(target); |
| 497 if (IsDeleted() || |
| 498 face_index >= level_infos_.size() || |
| 499 level >= static_cast<GLint>(level_infos_[face_index].size())) { |
| 500 return true; |
| 501 } |
| 502 |
| 503 TextureInfo::LevelInfo& info = level_infos_[face_index][level]; |
| 504 |
| 505 DCHECK(target == info.target); |
| 506 |
| 507 if (info.target == 0 || |
| 508 info.cleared || |
| 509 info.width == 0 || |
| 510 info.height == 0 || |
| 511 info.depth == 0) { |
| 512 return true; |
| 513 } |
| 514 |
| 515 DCHECK_NE(0, num_uncleared_mips_); |
| 516 --num_uncleared_mips_; |
| 517 |
| 518 // NOTE: It seems kind of gross to call back into the decoder for this |
| 519 // but only the decoder knows all the state (like unpack_alignment_) that's |
| 520 // needed to be able to call GL correctly. |
| 521 info.cleared = decoder->ClearLevel( |
| 522 service_id_, target_, info.target, info.level, info.format, info.type, |
| 523 info.width, info.height); |
| 524 if (!info.cleared) { |
| 525 ++num_uncleared_mips_; |
| 526 } |
| 527 return info.cleared; |
| 528 } |
| 529 |
403 TextureManager::TextureManager( | 530 TextureManager::TextureManager( |
404 GLint max_texture_size, | 531 GLint max_texture_size, |
405 GLint max_cube_map_texture_size) | 532 GLint max_cube_map_texture_size) |
406 : max_texture_size_(max_texture_size), | 533 : max_texture_size_(max_texture_size), |
407 max_cube_map_texture_size_(max_cube_map_texture_size), | 534 max_cube_map_texture_size_(max_cube_map_texture_size), |
408 max_levels_(ComputeMipMapCount(max_texture_size, | 535 max_levels_(ComputeMipMapCount(max_texture_size, |
409 max_texture_size, | 536 max_texture_size, |
410 max_texture_size)), | 537 max_texture_size)), |
411 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, | 538 max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, |
412 max_cube_map_texture_size, | 539 max_cube_map_texture_size, |
413 max_cube_map_texture_size)), | 540 max_cube_map_texture_size)), |
414 num_unrenderable_textures_(0), | 541 num_unrenderable_textures_(0), |
| 542 num_unsafe_textures_(0), |
| 543 num_uncleared_mips_(0), |
415 black_2d_texture_id_(0), | 544 black_2d_texture_id_(0), |
416 black_cube_texture_id_(0) { | 545 black_cube_texture_id_(0) { |
417 } | 546 } |
418 | 547 |
419 bool TextureManager::Initialize(const FeatureInfo* feature_info) { | 548 bool TextureManager::Initialize(const FeatureInfo* feature_info) { |
420 // TODO(gman): The default textures have to be real textures, not the 0 | 549 // TODO(gman): The default textures have to be real textures, not the 0 |
421 // texture because we simulate non shared resources on top of shared | 550 // texture because we simulate non shared resources on top of shared |
422 // resources and all contexts that share resource share the same default | 551 // resources and all contexts that share resource share the same default |
423 // texture. | 552 // texture. |
424 | 553 |
425 // Make default textures and texture for replacing non-renderable textures. | 554 // Make default textures and texture for replacing non-renderable textures. |
426 GLuint ids[4]; | 555 GLuint ids[4]; |
427 glGenTextures(arraysize(ids), ids); | 556 glGenTextures(arraysize(ids), ids); |
428 static uint8 black[] = {0, 0, 0, 255}; | 557 static uint8 black[] = {0, 0, 0, 255}; |
429 for (int ii = 0; ii < 2; ++ii) { | 558 for (int ii = 0; ii < 2; ++ii) { |
430 glBindTexture(GL_TEXTURE_2D, ids[ii]); | 559 glBindTexture(GL_TEXTURE_2D, ids[ii]); |
431 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, | 560 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, |
432 GL_UNSIGNED_BYTE, black); | 561 GL_UNSIGNED_BYTE, black); |
433 glBindTexture(GL_TEXTURE_CUBE_MAP, ids[2 + ii]); | 562 glBindTexture(GL_TEXTURE_CUBE_MAP, ids[2 + ii]); |
434 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { | 563 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { |
435 glTexImage2D(GLES2Util::IndexToGLFaceTarget(ii), 0, GL_RGBA, 1, 1, 0, | 564 glTexImage2D(GLES2Util::IndexToGLFaceTarget(ii), 0, GL_RGBA, 1, 1, 0, |
436 GL_RGBA, GL_UNSIGNED_BYTE, black); | 565 GL_RGBA, GL_UNSIGNED_BYTE, black); |
437 } | 566 } |
438 } | 567 } |
439 glBindTexture(GL_TEXTURE_2D, 0); | 568 glBindTexture(GL_TEXTURE_2D, 0); |
440 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); | 569 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); |
441 | 570 |
| 571 // Since we are manually setting up these textures |
| 572 // we need to manually manipulate some of the their bookkeeping. |
| 573 num_unrenderable_textures_ += 2; |
442 FeatureInfo temp_feature_info; | 574 FeatureInfo temp_feature_info; |
443 default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1])); | 575 default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1])); |
444 SetInfoTarget(feature_info, default_texture_2d_, GL_TEXTURE_2D); | 576 SetInfoTarget(feature_info, default_texture_2d_, GL_TEXTURE_2D); |
445 default_texture_2d_->SetLevelInfo(&temp_feature_info, | 577 SetLevelInfo(&temp_feature_info, default_texture_2d_, |
446 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 578 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); |
447 default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3])); | 579 default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3])); |
448 SetInfoTarget(feature_info, default_texture_cube_map_, GL_TEXTURE_CUBE_MAP); | 580 SetInfoTarget(feature_info, default_texture_cube_map_, GL_TEXTURE_CUBE_MAP); |
449 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { | 581 for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { |
450 default_texture_cube_map_->SetLevelInfo( | 582 SetLevelInfo( |
451 &temp_feature_info, GLES2Util::IndexToGLFaceTarget(ii), | 583 &temp_feature_info, default_texture_cube_map_, |
452 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 584 GLES2Util::IndexToGLFaceTarget(ii), |
| 585 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); |
453 } | 586 } |
454 | 587 |
455 black_2d_texture_id_ = ids[0]; | 588 black_2d_texture_id_ = ids[0]; |
456 black_cube_texture_id_ = ids[2]; | 589 black_cube_texture_id_ = ids[2]; |
457 | 590 |
458 if (feature_info->feature_flags().oes_egl_image_external) { | 591 if (feature_info->feature_flags().oes_egl_image_external) { |
| 592 // Since we are manually setting up these textures |
| 593 // we need to manually manipulate some of the their bookkeeping. |
| 594 num_unrenderable_textures_ += 1; |
459 GLuint external_ids[2]; | 595 GLuint external_ids[2]; |
460 glGenTextures(arraysize(external_ids), external_ids); | 596 glGenTextures(arraysize(external_ids), external_ids); |
461 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); | 597 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); |
462 default_texture_external_oes_ = TextureInfo::Ref( | 598 default_texture_external_oes_ = TextureInfo::Ref( |
463 new TextureInfo(external_ids[0])); | 599 new TextureInfo(external_ids[0])); |
464 SetInfoTarget(feature_info, | 600 SetInfoTarget(feature_info, |
465 default_texture_external_oes_, | 601 default_texture_external_oes_, |
466 GL_TEXTURE_EXTERNAL_OES); | 602 GL_TEXTURE_EXTERNAL_OES); |
467 default_texture_external_oes_->SetLevelInfo( | 603 default_texture_external_oes_->SetLevelInfo( |
468 &temp_feature_info, GL_TEXTURE_EXTERNAL_OES, 0, | 604 &temp_feature_info, GL_TEXTURE_EXTERNAL_OES, 0, |
469 GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); | 605 GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true); |
470 | 606 |
471 // Sampling a texture not associated with any EGLImage sibling will return | 607 // Sampling a texture not associated with any EGLImage sibling will return |
472 // black values according to the spec. | 608 // black values according to the spec. |
473 black_oes_external_texture_id_ = external_ids[1]; | 609 black_oes_external_texture_id_ = external_ids[1]; |
474 } | 610 } |
475 | 611 |
476 return true; | 612 return true; |
477 } | 613 } |
478 | 614 |
479 bool TextureManager::ValidForTarget( | 615 bool TextureManager::ValidForTarget( |
(...skipping 12 matching lines...) Expand all Loading... |
492 (level == 0 || feature_info->feature_flags().npot_ok || | 628 (level == 0 || feature_info->feature_flags().npot_ok || |
493 (!GLES2Util::IsNPOT(width) && | 629 (!GLES2Util::IsNPOT(width) && |
494 !GLES2Util::IsNPOT(height) && | 630 !GLES2Util::IsNPOT(height) && |
495 !GLES2Util::IsNPOT(depth))) && | 631 !GLES2Util::IsNPOT(depth))) && |
496 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && | 632 (target != GL_TEXTURE_CUBE_MAP || (width == height && depth == 1)) && |
497 (target != GL_TEXTURE_2D || (depth == 1)); | 633 (target != GL_TEXTURE_2D || (depth == 1)); |
498 } | 634 } |
499 | 635 |
500 void TextureManager::SetInfoTarget( | 636 void TextureManager::SetInfoTarget( |
501 const FeatureInfo* feature_info, | 637 const FeatureInfo* feature_info, |
502 TextureInfo* info, GLenum target) { | 638 TextureManager::TextureInfo* info, GLenum target) { |
503 DCHECK(info); | 639 DCHECK(info); |
504 if (!info->CanRender(feature_info)) { | 640 if (!info->CanRender(feature_info)) { |
| 641 DCHECK_NE(0, num_unrenderable_textures_); |
505 --num_unrenderable_textures_; | 642 --num_unrenderable_textures_; |
506 } | 643 } |
507 info->SetTarget(target, MaxLevelsForTarget(target)); | 644 info->SetTarget(target, MaxLevelsForTarget(target)); |
508 if (!info->CanRender(feature_info)) { | 645 if (!info->CanRender(feature_info)) { |
509 ++num_unrenderable_textures_; | 646 ++num_unrenderable_textures_; |
510 } | 647 } |
511 } | 648 } |
512 | 649 |
| 650 void TextureManager::SetLevelCleared( |
| 651 TextureManager::TextureInfo* info, GLenum target, GLint level) { |
| 652 DCHECK(info); |
| 653 DCHECK(!info->IsDeleted()); |
| 654 if (!info->SafeToRenderFrom()) { |
| 655 DCHECK_NE(0, num_unsafe_textures_); |
| 656 --num_unsafe_textures_; |
| 657 } |
| 658 num_uncleared_mips_ -= info->num_uncleared_mips(); |
| 659 DCHECK_GE(num_uncleared_mips_, 0); |
| 660 info->SetLevelCleared(target, level); |
| 661 num_uncleared_mips_ += info->num_uncleared_mips(); |
| 662 if (!info->SafeToRenderFrom()) { |
| 663 ++num_unsafe_textures_; |
| 664 } |
| 665 } |
| 666 |
| 667 bool TextureManager::ClearRenderableLevels( |
| 668 GLES2Decoder* decoder,TextureManager::TextureInfo* info) { |
| 669 DCHECK(info); |
| 670 DCHECK(!info->IsDeleted()); |
| 671 if (info->SafeToRenderFrom()) { |
| 672 return true; |
| 673 } |
| 674 DCHECK_NE(0, num_unsafe_textures_); |
| 675 --num_unsafe_textures_; |
| 676 num_uncleared_mips_ -= info->num_uncleared_mips(); |
| 677 DCHECK_GE(num_uncleared_mips_, 0); |
| 678 bool result = info->ClearRenderableLevels(decoder); |
| 679 num_uncleared_mips_ += info->num_uncleared_mips(); |
| 680 if (!info->SafeToRenderFrom()) { |
| 681 ++num_unsafe_textures_; |
| 682 } |
| 683 return result; |
| 684 } |
| 685 |
| 686 bool TextureManager::ClearTextureLevel( |
| 687 GLES2Decoder* decoder,TextureManager::TextureInfo* info, |
| 688 GLenum target, GLint level) { |
| 689 DCHECK(info); |
| 690 DCHECK(!info->IsDeleted()); |
| 691 if (info->num_uncleared_mips() == 0) { |
| 692 return true; |
| 693 } |
| 694 num_uncleared_mips_ -= info->num_uncleared_mips(); |
| 695 DCHECK_GE(num_uncleared_mips_, 0); |
| 696 if (!info->SafeToRenderFrom()) { |
| 697 DCHECK_NE(0, num_unsafe_textures_); |
| 698 --num_unsafe_textures_; |
| 699 } |
| 700 bool result = info->ClearLevel(decoder, target, level); |
| 701 info->UpdateCleared(); |
| 702 num_uncleared_mips_ += info->num_uncleared_mips(); |
| 703 if (!info->SafeToRenderFrom()) { |
| 704 ++num_unsafe_textures_; |
| 705 } |
| 706 return result; |
| 707 } |
| 708 |
513 void TextureManager::SetLevelInfo( | 709 void TextureManager::SetLevelInfo( |
514 const FeatureInfo* feature_info, | 710 const FeatureInfo* feature_info, |
515 TextureManager::TextureInfo* info, | 711 TextureManager::TextureInfo* info, |
516 GLenum target, | 712 GLenum target, |
517 GLint level, | 713 GLint level, |
518 GLenum internal_format, | 714 GLenum internal_format, |
519 GLsizei width, | 715 GLsizei width, |
520 GLsizei height, | 716 GLsizei height, |
521 GLsizei depth, | 717 GLsizei depth, |
522 GLint border, | 718 GLint border, |
523 GLenum format, | 719 GLenum format, |
524 GLenum type) { | 720 GLenum type, |
| 721 bool cleared) { |
525 DCHECK(info); | 722 DCHECK(info); |
526 DCHECK(!info->IsDeleted()); | 723 DCHECK(!info->IsDeleted()); |
527 if (!info->CanRender(feature_info)) { | 724 if (!info->CanRender(feature_info)) { |
| 725 DCHECK_NE(0, num_unrenderable_textures_); |
528 --num_unrenderable_textures_; | 726 --num_unrenderable_textures_; |
529 } | 727 } |
| 728 if (!info->SafeToRenderFrom()) { |
| 729 DCHECK_NE(0, num_unsafe_textures_); |
| 730 --num_unsafe_textures_; |
| 731 } |
| 732 num_uncleared_mips_ -= info->num_uncleared_mips(); |
| 733 DCHECK_GE(num_uncleared_mips_, 0); |
530 info->SetLevelInfo( | 734 info->SetLevelInfo( |
531 feature_info, target, level, internal_format, width, height, depth, | 735 feature_info, target, level, internal_format, width, height, depth, |
532 border, format, type); | 736 border, format, type, cleared); |
| 737 num_uncleared_mips_ += info->num_uncleared_mips(); |
533 if (!info->CanRender(feature_info)) { | 738 if (!info->CanRender(feature_info)) { |
534 ++num_unrenderable_textures_; | 739 ++num_unrenderable_textures_; |
535 } | 740 } |
| 741 if (!info->SafeToRenderFrom()) { |
| 742 ++num_unsafe_textures_; |
| 743 } |
536 } | 744 } |
537 | 745 |
538 bool TextureManager::SetParameter( | 746 bool TextureManager::SetParameter( |
539 const FeatureInfo* feature_info, | 747 const FeatureInfo* feature_info, |
540 TextureManager::TextureInfo* info, GLenum pname, GLint param) { | 748 TextureManager::TextureInfo* info, GLenum pname, GLint param) { |
541 DCHECK(feature_info); | 749 DCHECK(feature_info); |
542 DCHECK(info); | 750 DCHECK(info); |
543 DCHECK(!info->IsDeleted()); | 751 DCHECK(!info->IsDeleted()); |
544 if (!info->CanRender(feature_info)) { | 752 if (!info->CanRender(feature_info)) { |
| 753 DCHECK_NE(0, num_unrenderable_textures_); |
545 --num_unrenderable_textures_; | 754 --num_unrenderable_textures_; |
546 } | 755 } |
| 756 if (!info->SafeToRenderFrom()) { |
| 757 DCHECK_NE(0, num_unsafe_textures_); |
| 758 --num_unsafe_textures_; |
| 759 } |
547 bool result = info->SetParameter(feature_info, pname, param); | 760 bool result = info->SetParameter(feature_info, pname, param); |
548 if (!info->CanRender(feature_info)) { | 761 if (!info->CanRender(feature_info)) { |
549 ++num_unrenderable_textures_; | 762 ++num_unrenderable_textures_; |
550 } | 763 } |
| 764 if (!info->SafeToRenderFrom()) { |
| 765 ++num_unsafe_textures_; |
| 766 } |
551 return result; | 767 return result; |
552 } | 768 } |
553 | 769 |
554 bool TextureManager::MarkMipmapsGenerated( | 770 bool TextureManager::MarkMipmapsGenerated( |
555 const FeatureInfo* feature_info, | 771 const FeatureInfo* feature_info, |
556 TextureManager::TextureInfo* info) { | 772 TextureManager::TextureInfo* info) { |
557 DCHECK(info); | 773 DCHECK(info); |
558 DCHECK(!info->IsDeleted()); | 774 DCHECK(!info->IsDeleted()); |
559 if (!info->CanRender(feature_info)) { | 775 if (!info->CanRender(feature_info)) { |
| 776 DCHECK_NE(0, num_unrenderable_textures_); |
560 --num_unrenderable_textures_; | 777 --num_unrenderable_textures_; |
561 } | 778 } |
| 779 if (!info->SafeToRenderFrom()) { |
| 780 DCHECK_NE(0, num_unsafe_textures_); |
| 781 --num_unsafe_textures_; |
| 782 } |
| 783 num_uncleared_mips_ -= info->num_uncleared_mips(); |
| 784 DCHECK_GE(num_uncleared_mips_, 0); |
562 bool result = info->MarkMipmapsGenerated(feature_info); | 785 bool result = info->MarkMipmapsGenerated(feature_info); |
| 786 num_uncleared_mips_ += info->num_uncleared_mips(); |
563 if (!info->CanRender(feature_info)) { | 787 if (!info->CanRender(feature_info)) { |
564 ++num_unrenderable_textures_; | 788 ++num_unrenderable_textures_; |
565 } | 789 } |
| 790 if (!info->SafeToRenderFrom()) { |
| 791 ++num_unsafe_textures_; |
| 792 } |
566 return result; | 793 return result; |
567 } | 794 } |
568 | 795 |
569 TextureManager::TextureInfo* TextureManager::CreateTextureInfo( | 796 TextureManager::TextureInfo* TextureManager::CreateTextureInfo( |
570 const FeatureInfo* feature_info, | 797 const FeatureInfo* feature_info, |
571 GLuint client_id, GLuint service_id) { | 798 GLuint client_id, GLuint service_id) { |
572 TextureInfo::Ref info(new TextureInfo(service_id)); | 799 TextureInfo::Ref info(new TextureInfo(service_id)); |
573 std::pair<TextureInfoMap::iterator, bool> result = | 800 std::pair<TextureInfoMap::iterator, bool> result = |
574 texture_infos_.insert(std::make_pair(client_id, info)); | 801 texture_infos_.insert(std::make_pair(client_id, info)); |
575 DCHECK(result.second); | 802 DCHECK(result.second); |
576 if (!info->CanRender(feature_info)) { | 803 if (!info->CanRender(feature_info)) { |
577 ++num_unrenderable_textures_; | 804 ++num_unrenderable_textures_; |
578 } | 805 } |
| 806 if (!info->SafeToRenderFrom()) { |
| 807 ++num_unsafe_textures_; |
| 808 } |
| 809 num_uncleared_mips_ += info->num_uncleared_mips(); |
579 return info.get(); | 810 return info.get(); |
580 } | 811 } |
581 | 812 |
582 TextureManager::TextureInfo* TextureManager::GetTextureInfo( | 813 TextureManager::TextureInfo* TextureManager::GetTextureInfo( |
583 GLuint client_id) { | 814 GLuint client_id) { |
584 TextureInfoMap::iterator it = texture_infos_.find(client_id); | 815 TextureInfoMap::iterator it = texture_infos_.find(client_id); |
585 return it != texture_infos_.end() ? it->second : NULL; | 816 return it != texture_infos_.end() ? it->second : NULL; |
586 } | 817 } |
587 | 818 |
588 void TextureManager::RemoveTextureInfo( | 819 void TextureManager::RemoveTextureInfo( |
589 const FeatureInfo* feature_info, GLuint client_id) { | 820 const FeatureInfo* feature_info, GLuint client_id) { |
590 TextureInfoMap::iterator it = texture_infos_.find(client_id); | 821 TextureInfoMap::iterator it = texture_infos_.find(client_id); |
591 if (it != texture_infos_.end()) { | 822 if (it != texture_infos_.end()) { |
592 TextureInfo* info = it->second; | 823 TextureInfo* info = it->second; |
593 if (!info->CanRender(feature_info)) { | 824 if (!info->CanRender(feature_info)) { |
| 825 DCHECK_NE(0, num_unrenderable_textures_); |
594 --num_unrenderable_textures_; | 826 --num_unrenderable_textures_; |
595 } | 827 } |
| 828 if (!info->SafeToRenderFrom()) { |
| 829 DCHECK_NE(0, num_unsafe_textures_); |
| 830 --num_unsafe_textures_; |
| 831 } |
| 832 num_uncleared_mips_ -= info->num_uncleared_mips(); |
| 833 DCHECK_GE(num_uncleared_mips_, 0); |
596 info->MarkAsDeleted(); | 834 info->MarkAsDeleted(); |
597 texture_infos_.erase(it); | 835 texture_infos_.erase(it); |
598 } | 836 } |
599 } | 837 } |
600 | 838 |
601 bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const { | 839 bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const { |
602 // This doesn't need to be fast. It's only used during slow queries. | 840 // This doesn't need to be fast. It's only used during slow queries. |
603 for (TextureInfoMap::const_iterator it = texture_infos_.begin(); | 841 for (TextureInfoMap::const_iterator it = texture_infos_.begin(); |
604 it != texture_infos_.end(); ++it) { | 842 it != texture_infos_.end(); ++it) { |
605 if (it->second->service_id() == service_id) { | 843 if (it->second->service_id() == service_id) { |
606 *client_id = it->first; | 844 *client_id = it->first; |
607 return true; | 845 return true; |
608 } | 846 } |
609 } | 847 } |
610 return false; | 848 return false; |
611 } | 849 } |
612 | 850 |
613 } // namespace gles2 | 851 } // namespace gles2 |
614 } // namespace gpu | 852 } // namespace gpu |
615 | 853 |
616 | 854 |
OLD | NEW |