1/**************************************************************************/
2/* texture_storage.cpp */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifdef GLES3_ENABLED
32
33#include "texture_storage.h"
34#include "config.h"
35#include "drivers/gles3/effects/copy_effects.h"
36#include "utilities.h"
37
38#ifdef ANDROID_ENABLED
39#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR
40#endif
41
42using namespace GLES3;
43
44TextureStorage *TextureStorage::singleton = nullptr;
45
46TextureStorage *TextureStorage::get_singleton() {
47 return singleton;
48}
49
50static const GLenum _cube_side_enum[6] = {
51 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
52 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
53 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
54 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
55 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
56 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
57};
58
59TextureStorage::TextureStorage() {
60 singleton = this;
61
62 system_fbo = 0;
63
64 { //create default textures
65 { // White Textures
66
67 Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
68 image->fill(Color(1, 1, 1, 1));
69 image->generate_mipmaps();
70
71 default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();
72 texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);
73
74 Vector<Ref<Image>> images;
75 images.push_back(image);
76
77 default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE] = texture_allocate();
78 texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE], images, RS::TEXTURE_LAYERED_2D_ARRAY);
79
80 for (int i = 0; i < 3; i++) {
81 images.push_back(image);
82 }
83
84 default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE] = texture_allocate();
85 texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE], image->get_format(), 4, 4, 4, false, images);
86
87 for (int i = 0; i < 2; i++) {
88 images.push_back(image);
89 }
90
91 default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE] = texture_allocate();
92 texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE], images, RS::TEXTURE_LAYERED_CUBEMAP);
93 }
94
95 { // black
96 Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
97 image->fill(Color(0, 0, 0, 1));
98 image->generate_mipmaps();
99
100 default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();
101 texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);
102
103 Vector<Ref<Image>> images;
104
105 for (int i = 0; i < 4; i++) {
106 images.push_back(image);
107 }
108
109 default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK] = texture_allocate();
110 texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK], image->get_format(), 4, 4, 4, false, images);
111
112 for (int i = 0; i < 2; i++) {
113 images.push_back(image);
114 }
115 default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK] = texture_allocate();
116 texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP);
117 }
118
119 { // transparent black
120 Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
121 image->fill(Color(0, 0, 0, 0));
122 image->generate_mipmaps();
123
124 default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate();
125 texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image);
126 }
127
128 {
129 Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
130 image->fill(Color(0.5, 0.5, 1, 1));
131 image->generate_mipmaps();
132
133 default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();
134 texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);
135 }
136
137 {
138 Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
139 image->fill(Color(1.0, 0.5, 1, 1));
140 image->generate_mipmaps();
141
142 default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();
143 texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);
144 }
145
146 {
147 unsigned char pixel_data[4 * 4 * 4];
148 for (int i = 0; i < 16; i++) {
149 pixel_data[i * 4 + 0] = 0;
150 pixel_data[i * 4 + 1] = 0;
151 pixel_data[i * 4 + 2] = 0;
152 pixel_data[i * 4 + 3] = 0;
153 }
154
155 default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT] = texture_allocate();
156 Texture texture;
157 texture.width = 4;
158 texture.height = 4;
159 texture.format = Image::FORMAT_RGBA8;
160 texture.type = Texture::TYPE_2D;
161 texture.target = GL_TEXTURE_2D;
162 texture.active = true;
163 glGenTextures(1, &texture.tex_id);
164 texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT], texture);
165
166 glBindTexture(GL_TEXTURE_2D, texture.tex_id);
167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 4, 4, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixel_data);
168 GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 4, "Default uint texture");
169 texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
170 }
171 {
172 uint16_t pixel_data[4 * 4];
173 for (int i = 0; i < 16; i++) {
174 pixel_data[i] = Math::make_half_float(1.0f);
175 }
176
177 default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH] = texture_allocate();
178 Texture texture;
179 texture.width = 4;
180 texture.height = 4;
181 texture.format = Image::FORMAT_RGBA8;
182 texture.type = Texture::TYPE_2D;
183 texture.target = GL_TEXTURE_2D;
184 texture.active = true;
185 glGenTextures(1, &texture.tex_id);
186 texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH], texture);
187
188 glBindTexture(GL_TEXTURE_2D, texture.tex_id);
189 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 4, 4, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixel_data);
190 GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 2, "Default depth texture");
191 texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
192 }
193 }
194
195 glBindTexture(GL_TEXTURE_2D, 0);
196
197 { // Atlas Texture initialize.
198 uint8_t pixel_data[4 * 4 * 4];
199 for (int i = 0; i < 16; i++) {
200 pixel_data[i * 4 + 0] = 0;
201 pixel_data[i * 4 + 1] = 0;
202 pixel_data[i * 4 + 2] = 0;
203 pixel_data[i * 4 + 3] = 255;
204 }
205
206 glGenTextures(1, &texture_atlas.texture);
207 glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
208 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data);
209 GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, 4 * 4 * 4, "Texture atlas (Default)");
210 }
211
212 glBindTexture(GL_TEXTURE_2D, 0);
213
214 {
215 sdf_shader.shader.initialize();
216 sdf_shader.shader_version = sdf_shader.shader.version_create();
217 }
218
219#ifdef GLES_OVER_GL
220 glEnable(GL_PROGRAM_POINT_SIZE);
221#endif
222}
223
224TextureStorage::~TextureStorage() {
225 singleton = nullptr;
226 for (int i = 0; i < DEFAULT_GL_TEXTURE_MAX; i++) {
227 texture_free(default_gl_textures[i]);
228 }
229 if (texture_atlas.texture != 0) {
230 GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
231 }
232 texture_atlas.texture = 0;
233 glDeleteFramebuffers(1, &texture_atlas.framebuffer);
234 texture_atlas.framebuffer = 0;
235 sdf_shader.shader.version_free(sdf_shader.shader_version);
236}
237
238//TODO, move back to storage
239bool TextureStorage::can_create_resources_async() const {
240 return false;
241}
242
243/* Canvas Texture API */
244
245RID TextureStorage::canvas_texture_allocate() {
246 return canvas_texture_owner.allocate_rid();
247}
248
249void TextureStorage::canvas_texture_initialize(RID p_rid) {
250 canvas_texture_owner.initialize_rid(p_rid);
251}
252
253void TextureStorage::canvas_texture_free(RID p_rid) {
254 canvas_texture_owner.free(p_rid);
255}
256
257void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
258 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
259 ERR_FAIL_NULL(ct);
260
261 switch (p_channel) {
262 case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
263 ct->diffuse = p_texture;
264 } break;
265 case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
266 ct->normal_map = p_texture;
267 } break;
268 case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
269 ct->specular = p_texture;
270 } break;
271 }
272}
273
274void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
275 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
276 ERR_FAIL_NULL(ct);
277
278 ct->specular_color.r = p_specular_color.r;
279 ct->specular_color.g = p_specular_color.g;
280 ct->specular_color.b = p_specular_color.b;
281 ct->specular_color.a = p_shininess;
282}
283
284void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
285 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
286 ERR_FAIL_NULL(ct);
287
288 ct->texture_filter = p_filter;
289}
290
291void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
292 CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
293 ERR_FAIL_NULL(ct);
294
295 ct->texture_repeat = p_repeat;
296}
297
298/* Texture API */
299
300Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {
301 Config *config = Config::get_singleton();
302 r_gl_format = 0;
303 Ref<Image> image = p_image;
304 r_compressed = false;
305 r_real_format = p_format;
306
307 bool need_decompress = false;
308 bool decompress_ra_to_rg = false;
309
310 switch (p_format) {
311 case Image::FORMAT_L8: {
312#ifdef GLES_OVER_GL
313 r_gl_internal_format = GL_R8;
314 r_gl_format = GL_RED;
315 r_gl_type = GL_UNSIGNED_BYTE;
316#else
317 r_gl_internal_format = GL_LUMINANCE;
318 r_gl_format = GL_LUMINANCE;
319 r_gl_type = GL_UNSIGNED_BYTE;
320#endif
321 } break;
322 case Image::FORMAT_LA8: {
323#ifdef GLES_OVER_GL
324 r_gl_internal_format = GL_RG8;
325 r_gl_format = GL_RG;
326 r_gl_type = GL_UNSIGNED_BYTE;
327#else
328 r_gl_internal_format = GL_LUMINANCE_ALPHA;
329 r_gl_format = GL_LUMINANCE_ALPHA;
330 r_gl_type = GL_UNSIGNED_BYTE;
331#endif
332 } break;
333 case Image::FORMAT_R8: {
334 r_gl_internal_format = GL_R8;
335 r_gl_format = GL_RED;
336 r_gl_type = GL_UNSIGNED_BYTE;
337
338 } break;
339 case Image::FORMAT_RG8: {
340 r_gl_internal_format = GL_RG8;
341 r_gl_format = GL_RG;
342 r_gl_type = GL_UNSIGNED_BYTE;
343
344 } break;
345 case Image::FORMAT_RGB8: {
346 r_gl_internal_format = GL_RGB8;
347 r_gl_format = GL_RGB;
348 r_gl_type = GL_UNSIGNED_BYTE;
349
350 } break;
351 case Image::FORMAT_RGBA8: {
352 r_gl_format = GL_RGBA;
353 r_gl_internal_format = GL_RGBA8;
354 r_gl_type = GL_UNSIGNED_BYTE;
355
356 } break;
357 case Image::FORMAT_RGBA4444: {
358 r_gl_internal_format = GL_RGBA4;
359 r_gl_format = GL_RGBA;
360 r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;
361
362 } break;
363 case Image::FORMAT_RF: {
364 r_gl_internal_format = GL_R32F;
365 r_gl_format = GL_RED;
366 r_gl_type = GL_FLOAT;
367
368 } break;
369 case Image::FORMAT_RGF: {
370 r_gl_internal_format = GL_RG32F;
371 r_gl_format = GL_RG;
372 r_gl_type = GL_FLOAT;
373
374 } break;
375 case Image::FORMAT_RGBF: {
376 r_gl_internal_format = GL_RGB32F;
377 r_gl_format = GL_RGB;
378 r_gl_type = GL_FLOAT;
379
380 } break;
381 case Image::FORMAT_RGBAF: {
382 r_gl_internal_format = GL_RGBA32F;
383 r_gl_format = GL_RGBA;
384 r_gl_type = GL_FLOAT;
385
386 } break;
387 case Image::FORMAT_RH: {
388 r_gl_internal_format = GL_R16F;
389 r_gl_format = GL_RED;
390 r_gl_type = GL_HALF_FLOAT;
391 } break;
392 case Image::FORMAT_RGH: {
393 r_gl_internal_format = GL_RG16F;
394 r_gl_format = GL_RG;
395 r_gl_type = GL_HALF_FLOAT;
396
397 } break;
398 case Image::FORMAT_RGBH: {
399 r_gl_internal_format = GL_RGB16F;
400 r_gl_format = GL_RGB;
401 r_gl_type = GL_HALF_FLOAT;
402
403 } break;
404 case Image::FORMAT_RGBAH: {
405 r_gl_internal_format = GL_RGBA16F;
406 r_gl_format = GL_RGBA;
407 r_gl_type = GL_HALF_FLOAT;
408
409 } break;
410 case Image::FORMAT_RGBE9995: {
411 r_gl_internal_format = GL_RGB9_E5;
412 r_gl_format = GL_RGB;
413 r_gl_type = GL_UNSIGNED_INT_5_9_9_9_REV;
414
415 } break;
416 case Image::FORMAT_DXT1: {
417 if (config->s3tc_supported) {
418 r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
419 r_gl_format = GL_RGBA;
420 r_gl_type = GL_UNSIGNED_BYTE;
421 r_compressed = true;
422 } else {
423 need_decompress = true;
424 }
425 } break;
426 case Image::FORMAT_DXT3: {
427 if (config->s3tc_supported) {
428 r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
429 r_gl_format = GL_RGBA;
430 r_gl_type = GL_UNSIGNED_BYTE;
431 r_compressed = true;
432 } else {
433 need_decompress = true;
434 }
435 } break;
436 case Image::FORMAT_DXT5: {
437 if (config->s3tc_supported) {
438 r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
439 r_gl_format = GL_RGBA;
440 r_gl_type = GL_UNSIGNED_BYTE;
441 r_compressed = true;
442 } else {
443 need_decompress = true;
444 }
445 } break;
446 case Image::FORMAT_RGTC_R: {
447 if (config->rgtc_supported) {
448 r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;
449 r_gl_format = GL_RGBA;
450 r_gl_type = GL_UNSIGNED_BYTE;
451 r_compressed = true;
452 } else {
453 need_decompress = true;
454 }
455 } break;
456 case Image::FORMAT_RGTC_RG: {
457 if (config->rgtc_supported) {
458 r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;
459 r_gl_format = GL_RGBA;
460 r_gl_type = GL_UNSIGNED_BYTE;
461 r_compressed = true;
462 } else {
463 need_decompress = true;
464 }
465 } break;
466 case Image::FORMAT_BPTC_RGBA: {
467 if (config->bptc_supported) {
468 r_gl_internal_format = _EXT_COMPRESSED_RGBA_BPTC_UNORM;
469 r_gl_format = GL_RGBA;
470 r_gl_type = GL_UNSIGNED_BYTE;
471 r_compressed = true;
472 } else {
473 need_decompress = true;
474 }
475 } break;
476 case Image::FORMAT_BPTC_RGBF: {
477 if (config->bptc_supported) {
478 r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
479 r_gl_format = GL_RGB;
480 r_gl_type = GL_FLOAT;
481 r_compressed = true;
482 } else {
483 need_decompress = true;
484 }
485 } break;
486 case Image::FORMAT_BPTC_RGBFU: {
487 if (config->bptc_supported) {
488 r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
489 r_gl_format = GL_RGB;
490 r_gl_type = GL_FLOAT;
491 r_compressed = true;
492 } else {
493 need_decompress = true;
494 }
495 } break;
496 case Image::FORMAT_ETC2_R11: {
497 if (config->etc2_supported) {
498 r_gl_internal_format = _EXT_COMPRESSED_R11_EAC;
499 r_gl_format = GL_RED;
500 r_gl_type = GL_UNSIGNED_BYTE;
501 r_compressed = true;
502
503 } else {
504 need_decompress = true;
505 }
506 } break;
507 case Image::FORMAT_ETC2_R11S: {
508 if (config->etc2_supported) {
509 r_gl_internal_format = _EXT_COMPRESSED_SIGNED_R11_EAC;
510 r_gl_format = GL_RED;
511 r_gl_type = GL_UNSIGNED_BYTE;
512 r_compressed = true;
513
514 } else {
515 need_decompress = true;
516 }
517 } break;
518 case Image::FORMAT_ETC2_RG11: {
519 if (config->etc2_supported) {
520 r_gl_internal_format = _EXT_COMPRESSED_RG11_EAC;
521 r_gl_format = GL_RG;
522 r_gl_type = GL_UNSIGNED_BYTE;
523 r_compressed = true;
524
525 } else {
526 need_decompress = true;
527 }
528 } break;
529 case Image::FORMAT_ETC2_RG11S: {
530 if (config->etc2_supported) {
531 r_gl_internal_format = _EXT_COMPRESSED_SIGNED_RG11_EAC;
532 r_gl_format = GL_RG;
533 r_gl_type = GL_UNSIGNED_BYTE;
534 r_compressed = true;
535
536 } else {
537 need_decompress = true;
538 }
539 } break;
540 case Image::FORMAT_ETC:
541 case Image::FORMAT_ETC2_RGB8: {
542 if (config->etc2_supported) {
543 r_gl_internal_format = _EXT_COMPRESSED_RGB8_ETC2;
544 r_gl_format = GL_RGB;
545 r_gl_type = GL_UNSIGNED_BYTE;
546 r_compressed = true;
547
548 } else {
549 need_decompress = true;
550 }
551 } break;
552 case Image::FORMAT_ETC2_RGBA8: {
553 if (config->etc2_supported) {
554 r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;
555 r_gl_format = GL_RGBA;
556 r_gl_type = GL_UNSIGNED_BYTE;
557 r_compressed = true;
558
559 } else {
560 need_decompress = true;
561 }
562 } break;
563 case Image::FORMAT_ETC2_RGB8A1: {
564 if (config->etc2_supported) {
565 r_gl_internal_format = _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
566 r_gl_format = GL_RGBA;
567 r_gl_type = GL_UNSIGNED_BYTE;
568 r_compressed = true;
569
570 } else {
571 need_decompress = true;
572 }
573 } break;
574 case Image::FORMAT_ETC2_RA_AS_RG: {
575#ifndef WEB_ENABLED
576 if (config->etc2_supported) {
577 r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;
578 r_gl_format = GL_RGBA;
579 r_gl_type = GL_UNSIGNED_BYTE;
580 r_compressed = true;
581 } else
582#endif
583 {
584 need_decompress = true;
585 }
586 decompress_ra_to_rg = true;
587 } break;
588 case Image::FORMAT_DXT5_RA_AS_RG: {
589#ifndef WEB_ENABLED
590 if (config->s3tc_supported) {
591 r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
592 r_gl_format = GL_RGBA;
593 r_gl_type = GL_UNSIGNED_BYTE;
594 r_compressed = true;
595 } else
596#endif
597 {
598 need_decompress = true;
599 }
600 decompress_ra_to_rg = true;
601 } break;
602 case Image::FORMAT_ASTC_4x4: {
603 if (config->astc_supported) {
604 r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;
605 r_gl_format = GL_RGBA;
606 r_gl_type = GL_UNSIGNED_BYTE;
607 r_compressed = true;
608
609 } else {
610 need_decompress = true;
611 }
612 } break;
613 case Image::FORMAT_ASTC_4x4_HDR: {
614 if (config->astc_hdr_supported) {
615 r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;
616 r_gl_format = GL_RGBA;
617 r_gl_type = GL_UNSIGNED_BYTE;
618 r_compressed = true;
619
620 } else {
621 need_decompress = true;
622 }
623 } break;
624 case Image::FORMAT_ASTC_8x8: {
625 if (config->astc_supported) {
626 r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;
627 r_gl_format = GL_RGBA;
628 r_gl_type = GL_UNSIGNED_BYTE;
629 r_compressed = true;
630
631 } else {
632 need_decompress = true;
633 }
634 } break;
635 case Image::FORMAT_ASTC_8x8_HDR: {
636 if (config->astc_hdr_supported) {
637 r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;
638 r_gl_format = GL_RGBA;
639 r_gl_type = GL_UNSIGNED_BYTE;
640 r_compressed = true;
641
642 } else {
643 need_decompress = true;
644 }
645 } break;
646 default: {
647 ERR_FAIL_V_MSG(Ref<Image>(), "The image format " + itos(p_format) + " is not supported by the GL Compatibility rendering backend.");
648 }
649 }
650
651 if (need_decompress || p_force_decompress) {
652 if (!image.is_null()) {
653 image = image->duplicate();
654 image->decompress();
655 ERR_FAIL_COND_V(image->is_compressed(), image);
656 if (decompress_ra_to_rg) {
657 image->convert_ra_rgba8_to_rg();
658 image->convert(Image::FORMAT_RG8);
659 }
660 switch (image->get_format()) {
661 case Image::FORMAT_RG8: {
662 r_gl_format = GL_RG;
663 r_gl_internal_format = GL_RG8;
664 r_gl_type = GL_UNSIGNED_BYTE;
665 r_real_format = Image::FORMAT_RG8;
666 r_compressed = false;
667 } break;
668 case Image::FORMAT_RGB8: {
669 r_gl_format = GL_RGB;
670 r_gl_internal_format = GL_RGB;
671 r_gl_type = GL_UNSIGNED_BYTE;
672 r_real_format = Image::FORMAT_RGB8;
673 r_compressed = false;
674 } break;
675 case Image::FORMAT_RGBA8: {
676 r_gl_format = GL_RGBA;
677 r_gl_internal_format = GL_RGBA;
678 r_gl_type = GL_UNSIGNED_BYTE;
679 r_real_format = Image::FORMAT_RGBA8;
680 r_compressed = false;
681 } break;
682 default: {
683 image->convert(Image::FORMAT_RGBA8);
684 r_gl_format = GL_RGBA;
685 r_gl_internal_format = GL_RGBA;
686 r_gl_type = GL_UNSIGNED_BYTE;
687 r_real_format = Image::FORMAT_RGBA8;
688 r_compressed = false;
689 } break;
690 }
691 }
692
693 return image;
694 }
695
696 return p_image;
697}
698
699RID TextureStorage::texture_allocate() {
700 return texture_owner.allocate_rid();
701}
702
703void TextureStorage::texture_free(RID p_texture) {
704 Texture *t = texture_owner.get_or_null(p_texture);
705 ERR_FAIL_NULL(t);
706 ERR_FAIL_COND(t->is_render_target);
707
708 if (t->canvas_texture) {
709 memdelete(t->canvas_texture);
710 }
711
712 if (t->tex_id != 0) {
713 if (!t->is_external) {
714 GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
715 }
716 t->tex_id = 0;
717 }
718
719 if (t->is_proxy && t->proxy_to.is_valid()) {
720 Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);
721 if (proxy_to) {
722 proxy_to->proxies.erase(p_texture);
723 }
724 }
725
726 texture_atlas_remove_texture(p_texture);
727
728 for (int i = 0; i < t->proxies.size(); i++) {
729 Texture *p = texture_owner.get_or_null(t->proxies[i]);
730 ERR_CONTINUE(!p);
731 p->proxy_to = RID();
732 p->tex_id = 0;
733 }
734
735 texture_owner.free(p_texture);
736}
737
738void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {
739 ERR_FAIL_COND(p_image.is_null());
740
741 Texture texture;
742 texture.width = p_image->get_width();
743 texture.height = p_image->get_height();
744 texture.alloc_width = texture.width;
745 texture.alloc_height = texture.height;
746 texture.mipmaps = p_image->get_mipmap_count() + 1;
747 texture.format = p_image->get_format();
748 texture.type = Texture::TYPE_2D;
749 texture.target = GL_TEXTURE_2D;
750 _get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
751 texture.total_data_size = p_image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);
752 texture.active = true;
753 glGenTextures(1, &texture.tex_id);
754 GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");
755 texture_owner.initialize_rid(p_texture, texture);
756 texture_set_data(p_texture, p_image);
757}
758
759void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
760 ERR_FAIL_COND(p_layers.is_empty());
761
762 ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);
763 ERR_FAIL_COND_MSG(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY, "Cubemap Arrays are not supported in the GL Compatibility backend.");
764
765 Ref<Image> image = p_layers[0];
766 {
767 int valid_width = 0;
768 int valid_height = 0;
769 bool valid_mipmaps = false;
770 Image::Format valid_format = Image::FORMAT_MAX;
771
772 for (int i = 0; i < p_layers.size(); i++) {
773 ERR_FAIL_COND(p_layers[i]->is_empty());
774
775 if (i == 0) {
776 valid_width = p_layers[i]->get_width();
777 valid_height = p_layers[i]->get_height();
778 valid_format = p_layers[i]->get_format();
779 valid_mipmaps = p_layers[i]->has_mipmaps();
780 } else {
781 ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);
782 ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);
783 ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);
784 ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);
785 }
786 }
787 }
788
789 Texture texture;
790 texture.width = image->get_width();
791 texture.height = image->get_height();
792 texture.alloc_width = texture.width;
793 texture.alloc_height = texture.height;
794 texture.mipmaps = image->get_mipmap_count() + 1;
795 texture.format = image->get_format();
796 texture.type = Texture::TYPE_LAYERED;
797 texture.layered_type = p_layered_type;
798 texture.target = p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D_ARRAY;
799 texture.layers = p_layers.size();
800 _get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);
801 texture.total_data_size = p_layers[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.layers;
802 texture.active = true;
803 glGenTextures(1, &texture.tex_id);
804 GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture Layered");
805 texture_owner.initialize_rid(p_texture, texture);
806 for (int i = 0; i < p_layers.size(); i++) {
807 _texture_set_data(p_texture, p_layers[i], i, i == 0);
808 }
809}
810
811void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
812 texture_owner.initialize_rid(p_texture, Texture());
813}
814
815// Called internally when texture_proxy_create(p_base) is called.
816// Note: p_base is the root and p_texture is the proxy.
817void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
818 Texture *texture = texture_owner.get_or_null(p_base);
819 ERR_FAIL_NULL(texture);
820 Texture proxy_tex;
821 proxy_tex.copy_from(*texture);
822 proxy_tex.proxy_to = p_base;
823 proxy_tex.is_render_target = false;
824 proxy_tex.is_proxy = true;
825 proxy_tex.proxies.clear();
826 texture->proxies.push_back(p_texture);
827 texture_owner.initialize_rid(p_texture, proxy_tex);
828}
829
830RID TextureStorage::texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
831 Texture texture;
832 texture.active = true;
833 texture.is_external = true;
834 texture.type = p_type;
835
836 switch (p_type) {
837 case Texture::TYPE_2D: {
838 texture.target = GL_TEXTURE_2D;
839 } break;
840 case Texture::TYPE_3D: {
841 texture.target = GL_TEXTURE_3D;
842 } break;
843 case Texture::TYPE_LAYERED: {
844 texture.target = GL_TEXTURE_2D_ARRAY;
845 } break;
846 }
847
848 texture.real_format = texture.format = p_format;
849 texture.tex_id = p_image;
850 texture.alloc_width = texture.width = p_width;
851 texture.alloc_height = texture.height = p_height;
852 texture.depth = p_depth;
853 texture.layers = p_layers;
854 texture.layered_type = p_layered_type;
855
856 return texture_owner.make_rid(texture);
857}
858
859void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
860 texture_set_data(p_texture, p_image, p_layer);
861
862 Texture *tex = texture_owner.get_or_null(p_texture);
863 ERR_FAIL_NULL(tex);
864 GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
865
866#ifdef TOOLS_ENABLED
867 tex->image_cache_2d.unref();
868#endif
869}
870
871void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
872 Texture *tex = texture_owner.get_or_null(p_texture);
873 ERR_FAIL_NULL(tex);
874 ERR_FAIL_COND(!tex->is_proxy);
875 Texture *proxy_to = texture_owner.get_or_null(p_proxy_to);
876 ERR_FAIL_NULL(proxy_to);
877 ERR_FAIL_COND(proxy_to->is_proxy);
878
879 if (tex->proxy_to.is_valid()) {
880 Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to);
881 ERR_FAIL_NULL(prev_tex);
882 prev_tex->proxies.erase(p_texture);
883 }
884
885 *tex = *proxy_to;
886
887 tex->proxy_to = p_proxy_to;
888 tex->is_render_target = false;
889 tex->is_proxy = true;
890 tex->proxies.clear();
891 tex->canvas_texture = nullptr;
892 tex->tex_id = 0;
893 proxy_to->proxies.push_back(p_texture);
894}
895
896void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) {
897 //this could be better optimized to reuse an existing image , done this way
898 //for now to get it working
899 Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
900 image->fill(Color(1, 0, 1, 1));
901
902 texture_2d_initialize(p_texture, image);
903}
904
905void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RenderingServer::TextureLayeredType p_layered_type) {
906 //this could be better optimized to reuse an existing image , done this way
907 //for now to get it working
908 Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
909 image->fill(Color(1, 0, 1, 1));
910
911 Vector<Ref<Image>> images;
912 if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
913 images.push_back(image);
914 } else {
915 //cube
916 for (int i = 0; i < 6; i++) {
917 images.push_back(image);
918 }
919 }
920
921 texture_2d_layered_initialize(p_texture, images, p_layered_type);
922}
923
924void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {
925 //this could be better optimized to reuse an existing image , done this way
926 //for now to get it working
927 Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
928 image->fill(Color(1, 0, 1, 1));
929
930 Vector<Ref<Image>> images;
931 //cube
932 for (int i = 0; i < 4; i++) {
933 images.push_back(image);
934 }
935
936 texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, images);
937}
938
939Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
940 Texture *texture = texture_owner.get_or_null(p_texture);
941 ERR_FAIL_NULL_V(texture, Ref<Image>());
942
943#ifdef TOOLS_ENABLED
944 if (texture->image_cache_2d.is_valid() && !texture->is_render_target) {
945 return texture->image_cache_2d;
946 }
947#endif
948
949#ifdef GLES_OVER_GL
950 // OpenGL 3.3 supports glGetTexImage which is faster and simpler than glReadPixels.
951 // It also allows for reading compressed textures, mipmaps, and more formats.
952 Vector<uint8_t> data;
953
954 int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1);
955
956 data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
957 uint8_t *w = data.ptrw();
958
959 glActiveTexture(GL_TEXTURE0);
960
961 glBindTexture(texture->target, texture->tex_id);
962
963 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
964
965 for (int i = 0; i < texture->mipmaps; i++) {
966 int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i);
967
968 if (texture->compressed) {
969 glPixelStorei(GL_PACK_ALIGNMENT, 4);
970 glGetCompressedTexImage(texture->target, i, &w[ofs]);
971
972 } else {
973 glPixelStorei(GL_PACK_ALIGNMENT, 1);
974
975 glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &w[ofs]);
976 }
977 }
978
979 data.resize(data_size);
980
981 ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
982 Ref<Image> image = Image::create_from_data(texture->width, texture->height, texture->mipmaps > 1, texture->real_format, data);
983 ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
984 if (texture->format != texture->real_format) {
985 image->convert(texture->format);
986 }
987#else
988
989 Vector<uint8_t> data;
990
991 // On web and mobile we always read an RGBA8 image with no mipmaps.
992 int data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
993
994 data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
995 uint8_t *w = data.ptrw();
996
997 GLuint temp_framebuffer;
998 glGenFramebuffers(1, &temp_framebuffer);
999
1000 GLuint temp_color_texture;
1001 glGenTextures(1, &temp_color_texture);
1002
1003 glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
1004
1005 glBindTexture(GL_TEXTURE_2D, temp_color_texture);
1006 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1007
1008 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1009 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1010 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
1011
1012 glDepthMask(GL_FALSE);
1013 glDisable(GL_DEPTH_TEST);
1014 glDisable(GL_CULL_FACE);
1015 glDisable(GL_BLEND);
1016 glDepthFunc(GL_LEQUAL);
1017 glColorMask(1, 1, 1, 1);
1018 glActiveTexture(GL_TEXTURE0);
1019 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
1020
1021 glViewport(0, 0, texture->alloc_width, texture->alloc_height);
1022 glClearColor(0.0, 0.0, 0.0, 0.0);
1023 glClear(GL_COLOR_BUFFER_BIT);
1024
1025 CopyEffects::get_singleton()->copy_to_rect(Rect2i(0, 0, 1.0, 1.0));
1026
1027 glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);
1028
1029 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1030 glDeleteTextures(1, &temp_color_texture);
1031 glDeleteFramebuffers(1, &temp_framebuffer);
1032
1033 data.resize(data_size);
1034
1035 ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
1036 Ref<Image> image = Image::create_from_data(texture->width, texture->height, false, Image::FORMAT_RGBA8, data);
1037 ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
1038
1039 if (texture->format != Image::FORMAT_RGBA8) {
1040 image->convert(texture->format);
1041 }
1042
1043 if (texture->mipmaps > 1) {
1044 image->generate_mipmaps();
1045 }
1046
1047#endif
1048
1049#ifdef TOOLS_ENABLED
1050 if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {
1051 texture->image_cache_2d = image;
1052 }
1053#endif
1054
1055 return image;
1056}
1057
1058void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
1059 Texture *tex_to = texture_owner.get_or_null(p_texture);
1060 ERR_FAIL_NULL(tex_to);
1061 ERR_FAIL_COND(tex_to->is_proxy); //can't replace proxy
1062 Texture *tex_from = texture_owner.get_or_null(p_by_texture);
1063 ERR_FAIL_NULL(tex_from);
1064 ERR_FAIL_COND(tex_from->is_proxy); //can't replace proxy
1065
1066 if (tex_to == tex_from) {
1067 return;
1068 }
1069
1070 if (tex_to->canvas_texture) {
1071 memdelete(tex_to->canvas_texture);
1072 tex_to->canvas_texture = nullptr;
1073 }
1074
1075 if (tex_to->tex_id) {
1076 GLES3::Utilities::get_singleton()->texture_free_data(tex_to->tex_id);
1077 tex_to->tex_id = 0;
1078 }
1079
1080 Vector<RID> proxies_to_update = tex_to->proxies;
1081 Vector<RID> proxies_to_redirect = tex_from->proxies;
1082
1083 *tex_to = *tex_from;
1084
1085 tex_to->proxies = proxies_to_update; //restore proxies, so they can be updated
1086
1087 if (tex_to->canvas_texture) {
1088 tex_to->canvas_texture->diffuse = p_texture; //update
1089 }
1090
1091 for (int i = 0; i < proxies_to_update.size(); i++) {
1092 texture_proxy_update(proxies_to_update[i], p_texture);
1093 }
1094 for (int i = 0; i < proxies_to_redirect.size(); i++) {
1095 texture_proxy_update(proxies_to_redirect[i], p_texture);
1096 }
1097 //delete last, so proxies can be updated
1098 texture_owner.free(p_by_texture);
1099
1100 texture_atlas_mark_dirty_on_texture(p_texture);
1101}
1102
1103void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {
1104 Texture *texture = texture_owner.get_or_null(p_texture);
1105
1106 ERR_FAIL_NULL(texture);
1107 ERR_FAIL_COND(texture->is_render_target);
1108
1109 ERR_FAIL_COND(p_width <= 0 || p_width > 16384);
1110 ERR_FAIL_COND(p_height <= 0 || p_height > 16384);
1111 //real texture size is in alloc width and height
1112 texture->width = p_width;
1113 texture->height = p_height;
1114}
1115
1116void TextureStorage::texture_set_path(RID p_texture, const String &p_path) {
1117 Texture *texture = texture_owner.get_or_null(p_texture);
1118 ERR_FAIL_NULL(texture);
1119
1120 texture->path = p_path;
1121}
1122
1123String TextureStorage::texture_get_path(RID p_texture) const {
1124 Texture *texture = texture_owner.get_or_null(p_texture);
1125 ERR_FAIL_NULL_V(texture, "");
1126
1127 return texture->path;
1128}
1129
1130void TextureStorage::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1131 Texture *texture = texture_owner.get_or_null(p_texture);
1132 ERR_FAIL_NULL(texture);
1133
1134 texture->detect_3d_callback = p_callback;
1135 texture->detect_3d_callback_ud = p_userdata;
1136}
1137
1138void TextureStorage::texture_set_detect_srgb_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1139}
1140
1141void TextureStorage::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1142 Texture *texture = texture_owner.get_or_null(p_texture);
1143 ERR_FAIL_NULL(texture);
1144
1145 texture->detect_normal_callback = p_callback;
1146 texture->detect_normal_callback_ud = p_userdata;
1147}
1148
1149void TextureStorage::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
1150 Texture *texture = texture_owner.get_or_null(p_texture);
1151 ERR_FAIL_NULL(texture);
1152
1153 texture->detect_roughness_callback = p_callback;
1154 texture->detect_roughness_callback_ud = p_userdata;
1155}
1156
1157void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) {
1158 List<RID> textures;
1159 texture_owner.get_owned_list(&textures);
1160
1161 for (List<RID>::Element *E = textures.front(); E; E = E->next()) {
1162 Texture *t = texture_owner.get_or_null(E->get());
1163 if (!t) {
1164 continue;
1165 }
1166 RS::TextureInfo tinfo;
1167 tinfo.path = t->path;
1168 tinfo.format = t->format;
1169 tinfo.width = t->alloc_width;
1170 tinfo.height = t->alloc_height;
1171 tinfo.depth = 0;
1172 tinfo.bytes = t->total_data_size;
1173 r_info->push_back(tinfo);
1174 }
1175}
1176
1177void TextureStorage::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
1178 Texture *texture = texture_owner.get_or_null(p_texture);
1179 ERR_FAIL_NULL(texture);
1180
1181 texture->redraw_if_visible = p_enable;
1182}
1183
1184Size2 TextureStorage::texture_size_with_proxy(RID p_texture) {
1185 const Texture *texture = texture_owner.get_or_null(p_texture);
1186 ERR_FAIL_NULL_V(texture, Size2());
1187 if (texture->is_proxy) {
1188 const Texture *proxy = texture_owner.get_or_null(texture->proxy_to);
1189 return Size2(proxy->width, proxy->height);
1190 } else {
1191 return Size2(texture->width, texture->height);
1192 }
1193}
1194
1195void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type) {
1196}
1197
1198RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {
1199 return RID();
1200}
1201
1202uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {
1203 const Texture *texture = texture_owner.get_or_null(p_texture);
1204 ERR_FAIL_NULL_V(texture, 0);
1205
1206 return texture->tex_id;
1207}
1208
1209void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {
1210 _texture_set_data(p_texture, p_image, p_layer, false);
1211}
1212
1213void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer, bool initialize) {
1214 Texture *texture = texture_owner.get_or_null(p_texture);
1215
1216 ERR_FAIL_NULL(texture);
1217 if (texture->target == GL_TEXTURE_3D) {
1218 // Target is set to a 3D texture or array texture, exit early to avoid spamming errors
1219 return;
1220 }
1221 ERR_FAIL_COND(!texture->active);
1222 ERR_FAIL_COND(texture->is_render_target);
1223 ERR_FAIL_COND(p_image.is_null());
1224 ERR_FAIL_COND(texture->format != p_image->get_format());
1225
1226 ERR_FAIL_COND(!p_image->get_width());
1227 ERR_FAIL_COND(!p_image->get_height());
1228
1229 GLenum type;
1230 GLenum format;
1231 GLenum internal_format;
1232 bool compressed = false;
1233
1234 Image::Format real_format;
1235 Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), real_format, format, internal_format, type, compressed, texture->resize_to_po2);
1236 ERR_FAIL_COND(img.is_null());
1237 if (texture->resize_to_po2) {
1238 if (p_image->is_compressed()) {
1239 ERR_PRINT("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage.");
1240 }
1241
1242 if (img == p_image) {
1243 img = img->duplicate();
1244 }
1245 img->resize_to_po2(false);
1246 }
1247
1248 GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : texture->target;
1249
1250 Vector<uint8_t> read = img->get_data();
1251
1252 glActiveTexture(GL_TEXTURE0);
1253 glBindTexture(texture->target, texture->tex_id);
1254
1255#ifndef WEB_ENABLED
1256 switch (texture->format) {
1257#ifdef GLES_OVER_GL
1258 case Image::FORMAT_L8: {
1259 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
1260 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);
1261 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);
1262 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
1263 } break;
1264 case Image::FORMAT_LA8: {
1265 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
1266 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);
1267 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);
1268 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
1269 } break;
1270#endif // GLES3_OVER_GL
1271
1272 case Image::FORMAT_ETC2_RA_AS_RG:
1273 case Image::FORMAT_DXT5_RA_AS_RG: {
1274 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
1275 if (texture->format == real_format) {
1276 // Swizzle RA from compressed texture into RG
1277 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_G, GL_ALPHA);
1278 } else {
1279 // Converted textures are already in RG, leave as-is
1280 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
1281 }
1282 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
1283 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
1284 } break;
1285 default: {
1286 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
1287 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
1288 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
1289 glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
1290 } break;
1291 }
1292#endif // WEB_ENABLED
1293
1294 int mipmaps = img->has_mipmaps() ? img->get_mipmap_count() + 1 : 1;
1295
1296 // Set filtering and repeat state to default.
1297 if (mipmaps > 1) {
1298 texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
1299 } else {
1300 texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
1301 }
1302
1303 texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
1304
1305 int w = img->get_width();
1306 int h = img->get_height();
1307
1308 int tsize = 0;
1309
1310 for (int i = 0; i < mipmaps; i++) {
1311 int size, ofs;
1312 img->get_mipmap_offset_and_size(i, ofs, size);
1313
1314 if (compressed) {
1315 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1316
1317 int bw = w;
1318 int bh = h;
1319
1320 glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
1321 } else {
1322 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1323 if (texture->target == GL_TEXTURE_2D_ARRAY) {
1324 if (initialize) {
1325 glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, format, type, nullptr);
1326 }
1327 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]);
1328 } else {
1329 glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
1330 }
1331 }
1332
1333 tsize += size;
1334
1335 w = MAX(1, w >> 1);
1336 h = MAX(1, h >> 1);
1337 }
1338
1339 texture->total_data_size = tsize;
1340
1341 texture->stored_cube_sides |= (1 << p_layer);
1342
1343 texture->mipmaps = mipmaps;
1344}
1345
1346Image::Format TextureStorage::texture_get_format(RID p_texture) const {
1347 Texture *texture = texture_owner.get_or_null(p_texture);
1348
1349 ERR_FAIL_NULL_V(texture, Image::FORMAT_L8);
1350
1351 return texture->format;
1352}
1353
1354uint32_t TextureStorage::texture_get_texid(RID p_texture) const {
1355 Texture *texture = texture_owner.get_or_null(p_texture);
1356
1357 ERR_FAIL_NULL_V(texture, 0);
1358
1359 return texture->tex_id;
1360}
1361
1362uint32_t TextureStorage::texture_get_width(RID p_texture) const {
1363 Texture *texture = texture_owner.get_or_null(p_texture);
1364
1365 ERR_FAIL_NULL_V(texture, 0);
1366
1367 return texture->width;
1368}
1369
1370uint32_t TextureStorage::texture_get_height(RID p_texture) const {
1371 Texture *texture = texture_owner.get_or_null(p_texture);
1372
1373 ERR_FAIL_NULL_V(texture, 0);
1374
1375 return texture->height;
1376}
1377
1378uint32_t TextureStorage::texture_get_depth(RID p_texture) const {
1379 Texture *texture = texture_owner.get_or_null(p_texture);
1380
1381 ERR_FAIL_NULL_V(texture, 0);
1382
1383 return texture->depth;
1384}
1385
1386void TextureStorage::texture_bind(RID p_texture, uint32_t p_texture_no) {
1387 Texture *texture = texture_owner.get_or_null(p_texture);
1388
1389 ERR_FAIL_NULL(texture);
1390
1391 glActiveTexture(GL_TEXTURE0 + p_texture_no);
1392 glBindTexture(texture->target, texture->tex_id);
1393}
1394
1395/* TEXTURE ATLAS API */
1396
1397void TextureStorage::texture_add_to_texture_atlas(RID p_texture) {
1398 if (!texture_atlas.textures.has(p_texture)) {
1399 TextureAtlas::Texture t;
1400 t.users = 1;
1401 texture_atlas.textures[p_texture] = t;
1402 texture_atlas.dirty = true;
1403 } else {
1404 TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);
1405 t->users++;
1406 }
1407}
1408
1409void TextureStorage::texture_remove_from_texture_atlas(RID p_texture) {
1410 TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);
1411 ERR_FAIL_NULL(t);
1412 t->users--;
1413 if (t->users == 0) {
1414 texture_atlas.textures.erase(p_texture);
1415 // Do not mark it dirty, there is no need to since it remains working.
1416 }
1417}
1418
1419void TextureStorage::texture_atlas_mark_dirty_on_texture(RID p_texture) {
1420 if (texture_atlas.textures.has(p_texture)) {
1421 texture_atlas.dirty = true; // Mark it dirty since it was most likely modified.
1422 }
1423}
1424
1425void TextureStorage::texture_atlas_remove_texture(RID p_texture) {
1426 if (texture_atlas.textures.has(p_texture)) {
1427 texture_atlas.textures.erase(p_texture);
1428 // There is not much a point of making it dirty, texture can be removed next time the atlas is updated.
1429 }
1430}
1431
1432GLuint TextureStorage::texture_atlas_get_texture() const {
1433 return texture_atlas.texture;
1434}
1435
1436void TextureStorage::update_texture_atlas() {
1437 CopyEffects *copy_effects = CopyEffects::get_singleton();
1438 ERR_FAIL_NULL(copy_effects);
1439
1440 if (!texture_atlas.dirty) {
1441 return; //nothing to do
1442 }
1443
1444 texture_atlas.dirty = false;
1445
1446 if (texture_atlas.texture != 0) {
1447 GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
1448 texture_atlas.texture = 0;
1449 glDeleteFramebuffers(1, &texture_atlas.framebuffer);
1450 texture_atlas.framebuffer = 0;
1451 }
1452
1453 const int border = 2;
1454
1455 if (texture_atlas.textures.size()) {
1456 //generate atlas
1457 Vector<TextureAtlas::SortItem> itemsv;
1458 itemsv.resize(texture_atlas.textures.size());
1459 int base_size = 8;
1460
1461 int idx = 0;
1462
1463 for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {
1464 TextureAtlas::SortItem &si = itemsv.write[idx];
1465
1466 Texture *src_tex = get_texture(E.key);
1467
1468 si.size.width = (src_tex->width / border) + 1;
1469 si.size.height = (src_tex->height / border) + 1;
1470 si.pixel_size = Size2i(src_tex->width, src_tex->height);
1471
1472 if (base_size < si.size.width) {
1473 base_size = nearest_power_of_2_templated(si.size.width);
1474 }
1475
1476 si.texture = E.key;
1477 idx++;
1478 }
1479
1480 //sort items by size
1481 itemsv.sort();
1482
1483 //attempt to create atlas
1484 int item_count = itemsv.size();
1485 TextureAtlas::SortItem *items = itemsv.ptrw();
1486
1487 int atlas_height = 0;
1488
1489 while (true) {
1490 Vector<int> v_offsetsv;
1491 v_offsetsv.resize(base_size);
1492
1493 int *v_offsets = v_offsetsv.ptrw();
1494 memset(v_offsets, 0, sizeof(int) * base_size);
1495
1496 int max_height = 0;
1497
1498 for (int i = 0; i < item_count; i++) {
1499 //best fit
1500 TextureAtlas::SortItem &si = items[i];
1501 int best_idx = -1;
1502 int best_height = 0x7FFFFFFF;
1503 for (int j = 0; j <= base_size - si.size.width; j++) {
1504 int height = 0;
1505 for (int k = 0; k < si.size.width; k++) {
1506 int h = v_offsets[k + j];
1507 if (h > height) {
1508 height = h;
1509 if (height > best_height) {
1510 break; //already bad
1511 }
1512 }
1513 }
1514
1515 if (height < best_height) {
1516 best_height = height;
1517 best_idx = j;
1518 }
1519 }
1520
1521 //update
1522 for (int k = 0; k < si.size.width; k++) {
1523 v_offsets[k + best_idx] = best_height + si.size.height;
1524 }
1525
1526 si.pos.x = best_idx;
1527 si.pos.y = best_height;
1528
1529 if (si.pos.y + si.size.height > max_height) {
1530 max_height = si.pos.y + si.size.height;
1531 }
1532 }
1533
1534 if (max_height <= base_size * 2) {
1535 atlas_height = max_height;
1536 break; //good ratio, break;
1537 }
1538
1539 base_size *= 2;
1540 }
1541
1542 texture_atlas.size.width = base_size * border;
1543 texture_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
1544
1545 for (int i = 0; i < item_count; i++) {
1546 TextureAtlas::Texture *t = texture_atlas.textures.getptr(items[i].texture);
1547 t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
1548 t->uv_rect.size = items[i].pixel_size;
1549
1550 t->uv_rect.position /= Size2(texture_atlas.size);
1551 t->uv_rect.size /= Size2(texture_atlas.size);
1552 }
1553 } else {
1554 texture_atlas.size.width = 4;
1555 texture_atlas.size.height = 4;
1556 }
1557
1558 { // Atlas Texture initialize.
1559 // TODO validate texture atlas size with maximum texture size
1560 glGenTextures(1, &texture_atlas.texture);
1561 glActiveTexture(GL_TEXTURE0);
1562 glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
1563 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_atlas.size.width, texture_atlas.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1564 GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, texture_atlas.size.width * texture_atlas.size.height * 4, "Texture atlas");
1565
1566 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1567 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1568 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1569 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1570 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1571 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1572
1573 glGenFramebuffers(1, &texture_atlas.framebuffer);
1574 glBindFramebuffer(GL_FRAMEBUFFER, texture_atlas.framebuffer);
1575 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_atlas.texture, 0);
1576
1577 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1578
1579 if (status != GL_FRAMEBUFFER_COMPLETE) {
1580 glDeleteFramebuffers(1, &texture_atlas.framebuffer);
1581 texture_atlas.framebuffer = 0;
1582 GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
1583 texture_atlas.texture = 0;
1584 WARN_PRINT("Could not create texture atlas, status: " + get_framebuffer_error(status));
1585 return;
1586 }
1587 glViewport(0, 0, texture_atlas.size.width, texture_atlas.size.height);
1588 glClearColor(0.0, 0.0, 0.0, 0.0);
1589 glClear(GL_COLOR_BUFFER_BIT);
1590 glBindTexture(GL_TEXTURE_2D, 0);
1591 }
1592
1593 glDisable(GL_BLEND);
1594
1595 if (texture_atlas.textures.size()) {
1596 for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {
1597 TextureAtlas::Texture *t = texture_atlas.textures.getptr(E.key);
1598 Texture *src_tex = get_texture(E.key);
1599 glActiveTexture(GL_TEXTURE0);
1600 glBindTexture(GL_TEXTURE_2D, src_tex->tex_id);
1601 copy_effects->copy_to_rect(t->uv_rect);
1602 }
1603 }
1604 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1605}
1606
1607/* DECAL API */
1608
1609RID TextureStorage::decal_allocate() {
1610 return RID();
1611}
1612
1613void TextureStorage::decal_initialize(RID p_rid) {
1614}
1615
1616void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {
1617}
1618
1619void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
1620}
1621
1622void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
1623}
1624
1625void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
1626}
1627
1628void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
1629}
1630
1631void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
1632}
1633
1634void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
1635}
1636
1637void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
1638}
1639
1640void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
1641}
1642
1643AABB TextureStorage::decal_get_aabb(RID p_decal) const {
1644 return AABB();
1645}
1646
1647/* RENDER TARGET API */
1648
1649GLuint TextureStorage::system_fbo = 0;
1650
1651void TextureStorage::_update_render_target(RenderTarget *rt) {
1652 // do not allocate a render target with no size
1653 if (rt->size.x <= 0 || rt->size.y <= 0) {
1654 return;
1655 }
1656
1657 // do not allocate a render target that is attached to the screen
1658 if (rt->direct_to_screen) {
1659 rt->fbo = system_fbo;
1660 return;
1661 }
1662
1663 Config *config = Config::get_singleton();
1664
1665 rt->color_internal_format = rt->is_transparent ? GL_RGBA8 : GL_RGB10_A2;
1666 rt->color_format = GL_RGBA;
1667 rt->color_type = rt->is_transparent ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT_2_10_10_10_REV;
1668 rt->image_format = Image::FORMAT_RGBA8;
1669
1670 glDisable(GL_SCISSOR_TEST);
1671 glColorMask(1, 1, 1, 1);
1672 glDepthMask(GL_FALSE);
1673
1674 {
1675 Texture *texture;
1676 bool use_multiview = rt->view_count > 1 && config->multiview_supported;
1677 GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
1678
1679 /* Front FBO */
1680
1681 glGenFramebuffers(1, &rt->fbo);
1682 glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
1683
1684 // color
1685 if (rt->overridden.color.is_valid()) {
1686 texture = get_texture(rt->overridden.color);
1687 ERR_FAIL_NULL(texture);
1688
1689 rt->color = texture->tex_id;
1690 rt->size = Size2i(texture->width, texture->height);
1691 } else {
1692 texture = get_texture(rt->texture);
1693 ERR_FAIL_NULL(texture);
1694
1695 glGenTextures(1, &rt->color);
1696 glBindTexture(texture_target, rt->color);
1697
1698 if (use_multiview) {
1699 glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);
1700 } else {
1701 glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
1702 }
1703
1704 texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
1705 texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
1706
1707 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->color, rt->size.x * rt->size.y * rt->view_count * 4, "Render target color texture");
1708 }
1709#ifndef IOS_ENABLED
1710 if (use_multiview) {
1711 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count);
1712 } else {
1713#else
1714 {
1715#endif
1716 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
1717 }
1718
1719 // depth
1720 if (rt->overridden.depth.is_valid()) {
1721 texture = get_texture(rt->overridden.depth);
1722 ERR_FAIL_NULL(texture);
1723
1724 rt->depth = texture->tex_id;
1725 } else {
1726 glGenTextures(1, &rt->depth);
1727 glBindTexture(texture_target, rt->depth);
1728
1729 if (use_multiview) {
1730 glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
1731 } else {
1732 glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
1733 }
1734
1735 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1736 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1737 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1738 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1739
1740 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->depth, rt->size.x * rt->size.y * rt->view_count * 3, "Render target depth texture");
1741 }
1742#ifndef IOS_ENABLED
1743 if (use_multiview) {
1744 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count);
1745 } else {
1746#else
1747 {
1748#endif
1749 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
1750 }
1751
1752 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1753 if (status != GL_FRAMEBUFFER_COMPLETE) {
1754 glDeleteFramebuffers(1, &rt->fbo);
1755 if (rt->overridden.color.is_null()) {
1756 GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
1757 }
1758 if (rt->overridden.depth.is_null()) {
1759 GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);
1760 }
1761 rt->fbo = 0;
1762 rt->size.x = 0;
1763 rt->size.y = 0;
1764 rt->color = 0;
1765 rt->depth = 0;
1766 if (rt->overridden.color.is_null()) {
1767 texture->tex_id = 0;
1768 texture->active = false;
1769 }
1770 WARN_PRINT("Could not create render target, status: " + get_framebuffer_error(status));
1771 return;
1772 }
1773
1774 texture->is_render_target = true;
1775 texture->render_target = rt;
1776 if (rt->overridden.color.is_null()) {
1777 texture->format = rt->image_format;
1778 texture->real_format = rt->image_format;
1779 texture->target = texture_target;
1780 if (rt->view_count > 1 && config->multiview_supported) {
1781 texture->type = Texture::TYPE_LAYERED;
1782 texture->layers = rt->view_count;
1783 } else {
1784 texture->type = Texture::TYPE_2D;
1785 texture->layers = 1;
1786 }
1787 texture->gl_format_cache = rt->color_format;
1788 texture->gl_type_cache = GL_UNSIGNED_BYTE;
1789 texture->gl_internal_format_cache = rt->color_internal_format;
1790 texture->tex_id = rt->color;
1791 texture->width = rt->size.x;
1792 texture->alloc_width = rt->size.x;
1793 texture->height = rt->size.y;
1794 texture->alloc_height = rt->size.y;
1795 texture->active = true;
1796 }
1797 }
1798
1799 glClearColor(0, 0, 0, 0);
1800 glClear(GL_COLOR_BUFFER_BIT);
1801 glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
1802}
1803
1804void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
1805 ERR_FAIL_COND_MSG(rt->backbuffer_fbo != 0, "Cannot allocate RenderTarget backbuffer: already initialized.");
1806 ERR_FAIL_COND(rt->direct_to_screen);
1807 // Allocate mipmap chains for full screen blur
1808 // Limit mipmaps so smallest is 32x32 to avoid unnecessary framebuffer switches
1809 int count = MAX(1, Image::get_image_required_mipmaps(rt->size.x, rt->size.y, Image::FORMAT_RGBA8) - 4);
1810 if (rt->size.x > 40 && rt->size.y > 40) {
1811 GLsizei width = rt->size.x;
1812 GLsizei height = rt->size.y;
1813
1814 rt->mipmap_count = count;
1815
1816 glGenTextures(1, &rt->backbuffer);
1817 glBindTexture(GL_TEXTURE_2D, rt->backbuffer);
1818 uint32_t texture_size_bytes = 0;
1819
1820 for (int l = 0; l < count; l++) {
1821 texture_size_bytes += width * height * 4;
1822 glTexImage2D(GL_TEXTURE_2D, l, rt->color_internal_format, width, height, 0, rt->color_format, rt->color_type, nullptr);
1823 width = MAX(1, (width / 2));
1824 height = MAX(1, (height / 2));
1825 }
1826
1827 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1828 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);
1829
1830 glGenFramebuffers(1, &rt->backbuffer_fbo);
1831 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
1832
1833 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);
1834
1835 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1836 if (status != GL_FRAMEBUFFER_COMPLETE) {
1837 WARN_PRINT_ONCE("Cannot allocate mipmaps for canvas screen blur. Status: " + get_framebuffer_error(status));
1838 glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
1839 return;
1840 }
1841 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, texture_size_bytes, "Render target backbuffer color texture");
1842
1843 // Initialize all levels to clear black.
1844 for (int j = 0; j < count; j++) {
1845 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, j);
1846 glClearColor(0.0, 0.0, 0.0, 0.0);
1847 glClear(GL_COLOR_BUFFER_BIT);
1848 }
1849
1850 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);
1851
1852 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1854 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1856 }
1857}
1858void GLES3::TextureStorage::copy_scene_to_backbuffer(RenderTarget *rt, const bool uses_screen_texture, const bool uses_depth_texture) {
1859 if (rt->backbuffer != 0 && rt->backbuffer_depth != 0) {
1860 return;
1861 }
1862
1863 Config *config = Config::get_singleton();
1864 bool use_multiview = rt->view_count > 1 && config->multiview_supported;
1865 GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
1866 if (rt->backbuffer_fbo == 0) {
1867 glGenFramebuffers(1, &rt->backbuffer_fbo);
1868 }
1869 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
1870 if (rt->backbuffer == 0 && uses_screen_texture) {
1871 glGenTextures(1, &rt->backbuffer);
1872 glBindTexture(texture_target, rt->backbuffer);
1873 if (use_multiview) {
1874 glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);
1875 } else {
1876 glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
1877 }
1878 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, rt->size.x * rt->size.y * rt->view_count * 4, "Render target backbuffer color texture (3D)");
1879 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1880 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1881 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1882 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1883#ifndef IOS_ENABLED
1884 if (use_multiview) {
1885 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->backbuffer, 0, 0, rt->view_count);
1886 } else {
1887#else
1888 {
1889#endif
1890 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);
1891 }
1892 }
1893 if (rt->backbuffer_depth == 0 && uses_depth_texture) {
1894 glGenTextures(1, &rt->backbuffer_depth);
1895 glBindTexture(texture_target, rt->backbuffer_depth);
1896 if (use_multiview) {
1897 glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
1898 } else {
1899 glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
1900 }
1901 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer_depth, rt->size.x * rt->size.y * rt->view_count * 3, "Render target backbuffer depth texture");
1902
1903 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1904 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1905 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1906 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1907#ifndef IOS_ENABLED
1908 if (use_multiview) {
1909 glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, rt->backbuffer_depth, 0, 0, rt->view_count);
1910 } else {
1911#else
1912 {
1913#endif
1914 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->backbuffer_depth, 0);
1915 }
1916 }
1917}
1918void TextureStorage::_clear_render_target(RenderTarget *rt) {
1919 // there is nothing to clear when DIRECT_TO_SCREEN is used
1920 if (rt->direct_to_screen) {
1921 return;
1922 }
1923
1924 // Dispose of the cached fbo's and the allocated textures
1925 for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) {
1926 glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr());
1927 // Don't delete the current FBO, we'll do that a couple lines down.
1928 if (E.value.fbo != rt->fbo) {
1929 glDeleteFramebuffers(1, &E.value.fbo);
1930 }
1931 }
1932 rt->overridden.fbo_cache.clear();
1933
1934 if (rt->fbo) {
1935 glDeleteFramebuffers(1, &rt->fbo);
1936 rt->fbo = 0;
1937 }
1938
1939 if (rt->overridden.color.is_null()) {
1940 if (rt->texture.is_valid()) {
1941 Texture *tex = get_texture(rt->texture);
1942 tex->alloc_height = 0;
1943 tex->alloc_width = 0;
1944 tex->width = 0;
1945 tex->height = 0;
1946 tex->active = false;
1947 tex->render_target = nullptr;
1948 tex->is_render_target = false;
1949 tex->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);
1950 tex->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX);
1951 }
1952 } else {
1953 Texture *tex = get_texture(rt->overridden.color);
1954 tex->render_target = nullptr;
1955 tex->is_render_target = false;
1956 }
1957
1958 if (rt->overridden.color.is_valid()) {
1959 rt->overridden.color = RID();
1960 } else if (rt->color) {
1961 GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
1962 if (rt->texture.is_valid()) {
1963 Texture *tex = get_texture(rt->texture);
1964 tex->tex_id = 0;
1965 }
1966 }
1967 rt->color = 0;
1968
1969 if (rt->overridden.depth.is_valid()) {
1970 rt->overridden.depth = RID();
1971 } else if (rt->depth) {
1972 GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);
1973 }
1974 rt->depth = 0;
1975
1976 rt->overridden.velocity = RID();
1977 rt->overridden.is_overridden = false;
1978
1979 if (rt->backbuffer_fbo != 0) {
1980 glDeleteFramebuffers(1, &rt->backbuffer_fbo);
1981 GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer);
1982 rt->backbuffer = 0;
1983 rt->backbuffer_fbo = 0;
1984 }
1985 if (rt->backbuffer_depth != 0) {
1986 GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer_depth);
1987 rt->backbuffer_depth = 0;
1988 }
1989 _render_target_clear_sdf(rt);
1990}
1991
1992RID TextureStorage::render_target_create() {
1993 RenderTarget render_target;
1994 render_target.used_in_frame = false;
1995 render_target.clear_requested = false;
1996
1997 Texture t;
1998 t.active = true;
1999 t.render_target = &render_target;
2000 t.is_render_target = true;
2001
2002 render_target.texture = texture_owner.make_rid(t);
2003 _update_render_target(&render_target);
2004 return render_target_owner.make_rid(render_target);
2005}
2006
2007void TextureStorage::render_target_free(RID p_rid) {
2008 RenderTarget *rt = render_target_owner.get_or_null(p_rid);
2009 _clear_render_target(rt);
2010
2011 Texture *t = get_texture(rt->texture);
2012 if (t) {
2013 t->is_render_target = false;
2014 if (rt->overridden.color.is_null()) {
2015 texture_free(rt->texture);
2016 }
2017 //memdelete(t);
2018 }
2019 render_target_owner.free(p_rid);
2020}
2021
2022void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {
2023 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2024 ERR_FAIL_NULL(rt);
2025
2026 rt->position = Point2i(p_x, p_y);
2027}
2028
2029Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
2030 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2031 ERR_FAIL_NULL_V(rt, Point2i());
2032
2033 return rt->position;
2034};
2035
2036void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
2037 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2038 ERR_FAIL_NULL(rt);
2039
2040 if (p_width == rt->size.x && p_height == rt->size.y && p_view_count == rt->view_count) {
2041 return;
2042 }
2043 if (rt->overridden.color.is_valid()) {
2044 return;
2045 }
2046
2047 _clear_render_target(rt);
2048
2049 rt->size = Size2i(p_width, p_height);
2050 rt->view_count = p_view_count;
2051
2052 _update_render_target(rt);
2053}
2054
2055// TODO: convert to Size2i internally
2056Size2i TextureStorage::render_target_get_size(RID p_render_target) const {
2057 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2058 ERR_FAIL_NULL_V(rt, Size2i());
2059
2060 return rt->size;
2061}
2062
2063void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) {
2064 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2065 ERR_FAIL_NULL(rt);
2066 ERR_FAIL_COND(rt->direct_to_screen);
2067
2068 rt->overridden.velocity = p_velocity_texture;
2069
2070 if (rt->overridden.color == p_color_texture && rt->overridden.depth == p_depth_texture) {
2071 return;
2072 }
2073
2074 if (p_color_texture.is_null() && p_depth_texture.is_null()) {
2075 _clear_render_target(rt);
2076 _update_render_target(rt);
2077 return;
2078 }
2079
2080 if (!rt->overridden.is_overridden) {
2081 _clear_render_target(rt);
2082 }
2083
2084 rt->overridden.color = p_color_texture;
2085 rt->overridden.depth = p_depth_texture;
2086 rt->overridden.is_overridden = true;
2087
2088 uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id());
2089 hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key);
2090 hash_key = hash_fmix32(hash_key);
2091
2092 RBMap<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry>::Element *cache;
2093 if ((cache = rt->overridden.fbo_cache.find(hash_key)) != nullptr) {
2094 rt->fbo = cache->get().fbo;
2095 rt->color = cache->get().color;
2096 rt->depth = cache->get().depth;
2097 rt->size = cache->get().size;
2098 rt->texture = p_color_texture;
2099 return;
2100 }
2101
2102 _update_render_target(rt);
2103
2104 RenderTarget::RTOverridden::FBOCacheEntry new_entry;
2105 new_entry.fbo = rt->fbo;
2106 new_entry.color = rt->color;
2107 new_entry.depth = rt->depth;
2108 new_entry.size = rt->size;
2109 // Keep track of any textures we had to allocate because they weren't overridden.
2110 if (p_color_texture.is_null()) {
2111 new_entry.allocated_textures.push_back(rt->color);
2112 }
2113 if (p_depth_texture.is_null()) {
2114 new_entry.allocated_textures.push_back(rt->depth);
2115 }
2116 rt->overridden.fbo_cache.insert(hash_key, new_entry);
2117}
2118
2119RID TextureStorage::render_target_get_override_color(RID p_render_target) const {
2120 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2121 ERR_FAIL_NULL_V(rt, RID());
2122
2123 return rt->overridden.color;
2124}
2125
2126RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {
2127 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2128 ERR_FAIL_NULL_V(rt, RID());
2129
2130 return rt->overridden.depth;
2131}
2132
2133RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {
2134 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2135 ERR_FAIL_NULL_V(rt, RID());
2136
2137 return rt->overridden.velocity;
2138}
2139
2140RID TextureStorage::render_target_get_texture(RID p_render_target) {
2141 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2142 ERR_FAIL_NULL_V(rt, RID());
2143
2144 if (rt->overridden.color.is_valid()) {
2145 return rt->overridden.color;
2146 }
2147
2148 return rt->texture;
2149}
2150
2151void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_transparent) {
2152 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2153 ERR_FAIL_NULL(rt);
2154
2155 rt->is_transparent = p_transparent;
2156
2157 if (rt->overridden.color.is_null()) {
2158 _clear_render_target(rt);
2159 _update_render_target(rt);
2160 }
2161}
2162
2163bool TextureStorage::render_target_get_transparent(RID p_render_target) const {
2164 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2165 ERR_FAIL_NULL_V(rt, false);
2166
2167 return rt->is_transparent;
2168}
2169
2170void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) {
2171 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2172 ERR_FAIL_NULL(rt);
2173
2174 if (p_direct_to_screen == rt->direct_to_screen) {
2175 return;
2176 }
2177 // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as
2178 // those functions change how they operate depending on the value of DIRECT_TO_SCREEN
2179 _clear_render_target(rt);
2180 rt->direct_to_screen = p_direct_to_screen;
2181 if (rt->direct_to_screen) {
2182 rt->overridden.color = RID();
2183 rt->overridden.depth = RID();
2184 rt->overridden.velocity = RID();
2185 }
2186 _update_render_target(rt);
2187}
2188
2189bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {
2190 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2191 ERR_FAIL_NULL_V(rt, false);
2192
2193 return rt->direct_to_screen;
2194}
2195
2196bool TextureStorage::render_target_was_used(RID p_render_target) const {
2197 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2198 ERR_FAIL_NULL_V(rt, false);
2199
2200 return rt->used_in_frame;
2201}
2202
2203void TextureStorage::render_target_clear_used(RID p_render_target) {
2204 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2205 ERR_FAIL_NULL(rt);
2206
2207 rt->used_in_frame = false;
2208}
2209
2210void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
2211 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2212 ERR_FAIL_NULL(rt);
2213 if (p_msaa == rt->msaa) {
2214 return;
2215 }
2216
2217 WARN_PRINT("2D MSAA is not yet supported for GLES3.");
2218
2219 _clear_render_target(rt);
2220 rt->msaa = p_msaa;
2221 _update_render_target(rt);
2222}
2223
2224RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {
2225 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2226 ERR_FAIL_NULL_V(rt, RS::VIEWPORT_MSAA_DISABLED);
2227
2228 return rt->msaa;
2229}
2230
2231void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
2232 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2233 ERR_FAIL_NULL(rt);
2234 rt->clear_requested = true;
2235 rt->clear_color = p_clear_color;
2236}
2237
2238bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {
2239 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2240 ERR_FAIL_NULL_V(rt, false);
2241 return rt->clear_requested;
2242}
2243Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {
2244 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2245 ERR_FAIL_NULL_V(rt, Color());
2246 return rt->clear_color;
2247}
2248
2249void TextureStorage::render_target_disable_clear_request(RID p_render_target) {
2250 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2251 ERR_FAIL_NULL(rt);
2252 rt->clear_requested = false;
2253}
2254
2255void TextureStorage::render_target_do_clear_request(RID p_render_target) {
2256 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2257 ERR_FAIL_NULL(rt);
2258 if (!rt->clear_requested) {
2259 return;
2260 }
2261 glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
2262
2263 glClearBufferfv(GL_COLOR, 0, rt->clear_color.components);
2264 rt->clear_requested = false;
2265 glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
2266}
2267
2268void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
2269 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2270 ERR_FAIL_NULL(rt);
2271 if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
2272 return;
2273 }
2274
2275 rt->sdf_oversize = p_size;
2276 rt->sdf_scale = p_scale;
2277
2278 _render_target_clear_sdf(rt);
2279}
2280
2281Rect2i TextureStorage::_render_target_get_sdf_rect(const RenderTarget *rt) const {
2282 Size2i margin;
2283 int scale;
2284 switch (rt->sdf_oversize) {
2285 case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {
2286 scale = 100;
2287 } break;
2288 case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {
2289 scale = 120;
2290 } break;
2291 case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {
2292 scale = 150;
2293 } break;
2294 case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {
2295 scale = 200;
2296 } break;
2297 default: {
2298 }
2299 }
2300
2301 margin = (rt->size * scale / 100) - rt->size;
2302
2303 Rect2i r(Vector2i(), rt->size);
2304 r.position -= margin;
2305 r.size += margin * 2;
2306
2307 return r;
2308}
2309
2310Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {
2311 const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2312 ERR_FAIL_NULL_V(rt, Rect2i());
2313
2314 return _render_target_get_sdf_rect(rt);
2315}
2316
2317void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
2318 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2319 ERR_FAIL_NULL(rt);
2320
2321 rt->sdf_enabled = p_enabled;
2322}
2323
2324bool TextureStorage::render_target_is_sdf_enabled(RID p_render_target) const {
2325 const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2326 ERR_FAIL_NULL_V(rt, false);
2327
2328 return rt->sdf_enabled;
2329}
2330
2331GLuint TextureStorage::render_target_get_sdf_texture(RID p_render_target) {
2332 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2333 ERR_FAIL_NULL_V(rt, 0);
2334 if (rt->sdf_texture_read == 0) {
2335 Texture *texture = texture_owner.get_or_null(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK]);
2336 return texture->tex_id;
2337 }
2338
2339 return rt->sdf_texture_read;
2340}
2341
2342void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
2343 ERR_FAIL_COND(rt->sdf_texture_write_fb != 0);
2344
2345 Size2i size = _render_target_get_sdf_rect(rt).size;
2346
2347 glGenTextures(1, &rt->sdf_texture_write);
2348 glActiveTexture(GL_TEXTURE0);
2349 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);
2350 glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size.width, size.height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
2351 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_write, size.width * size.height, "SDF texture");
2352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2356 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2358
2359 glGenFramebuffers(1, &rt->sdf_texture_write_fb);
2360 glBindFramebuffer(GL_FRAMEBUFFER, rt->sdf_texture_write_fb);
2361 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_write, 0);
2362
2363 int scale;
2364 switch (rt->sdf_scale) {
2365 case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {
2366 scale = 100;
2367 } break;
2368 case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
2369 scale = 50;
2370 } break;
2371 case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
2372 scale = 25;
2373 } break;
2374 default: {
2375 scale = 100;
2376 } break;
2377 }
2378
2379 rt->process_size = size * scale / 100;
2380 rt->process_size.x = MAX(rt->process_size.x, 1);
2381 rt->process_size.y = MAX(rt->process_size.y, 1);
2382
2383 glGenTextures(2, rt->sdf_texture_process);
2384 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]);
2385 glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);
2386 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2387 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2392 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]");
2393
2394 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[1]);
2395 glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);
2396 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2397 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2398 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2399 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2400 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2401 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2402 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]");
2403
2404 glGenTextures(1, &rt->sdf_texture_read);
2405 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_read);
2406 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->process_size.width, rt->process_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2407 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2408 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2411 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2412 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2413 GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)");
2414}
2415
2416void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {
2417 if (rt->sdf_texture_write_fb != 0) {
2418 GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_read);
2419 GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_write);
2420 GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[0]);
2421 GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[1]);
2422
2423 glDeleteFramebuffers(1, &rt->sdf_texture_write_fb);
2424 rt->sdf_texture_read = 0;
2425 rt->sdf_texture_write = 0;
2426 rt->sdf_texture_process[0] = 0;
2427 rt->sdf_texture_process[1] = 0;
2428 rt->sdf_texture_write_fb = 0;
2429 }
2430}
2431
2432GLuint TextureStorage::render_target_get_sdf_framebuffer(RID p_render_target) {
2433 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2434 ERR_FAIL_NULL_V(rt, 0);
2435
2436 if (rt->sdf_texture_write_fb == 0) {
2437 _render_target_allocate_sdf(rt);
2438 }
2439
2440 return rt->sdf_texture_write_fb;
2441}
2442void TextureStorage::render_target_sdf_process(RID p_render_target) {
2443 CopyEffects *copy_effects = CopyEffects::get_singleton();
2444
2445 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2446 ERR_FAIL_NULL(rt);
2447 ERR_FAIL_COND(rt->sdf_texture_write_fb == 0);
2448
2449 Rect2i r = _render_target_get_sdf_rect(rt);
2450
2451 Size2i size = r.size;
2452 int32_t shift = 0;
2453
2454 bool shrink = false;
2455
2456 switch (rt->sdf_scale) {
2457 case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
2458 size[0] >>= 1;
2459 size[1] >>= 1;
2460 shift = 1;
2461 shrink = true;
2462 } break;
2463 case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
2464 size[0] >>= 2;
2465 size[1] >>= 2;
2466 shift = 2;
2467 shrink = true;
2468 } break;
2469 default: {
2470 };
2471 }
2472
2473 GLuint temp_fb;
2474 glGenFramebuffers(1, &temp_fb);
2475 glBindFramebuffer(GL_FRAMEBUFFER, temp_fb);
2476
2477 // Load
2478 CanvasSdfShaderGLES3::ShaderVariant variant = shrink ? CanvasSdfShaderGLES3::MODE_LOAD_SHRINK : CanvasSdfShaderGLES3::MODE_LOAD;
2479 bool success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
2480 if (!success) {
2481 return;
2482 }
2483
2484 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);
2485 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);
2486 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, 0, sdf_shader.shader_version, variant);
2487 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);
2488
2489 glActiveTexture(GL_TEXTURE0);
2490 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);
2491
2492 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[0], 0);
2493 glViewport(0, 0, size.width, size.height);
2494 glEnable(GL_SCISSOR_TEST);
2495 glScissor(0, 0, size.width, size.height);
2496
2497 copy_effects->draw_screen_triangle();
2498
2499 // Process
2500
2501 int stride = nearest_power_of_2_templated(MAX(size.width, size.height) / 2);
2502
2503 variant = CanvasSdfShaderGLES3::MODE_PROCESS;
2504 success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
2505 if (!success) {
2506 return;
2507 }
2508
2509 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);
2510 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);
2511 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);
2512 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);
2513
2514 bool swap = false;
2515
2516 //jumpflood
2517 while (stride > 0) {
2518 glBindTexture(GL_TEXTURE_2D, 0);
2519 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 0 : 1], 0);
2520 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);
2521
2522 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);
2523
2524 copy_effects->draw_screen_triangle();
2525
2526 stride /= 2;
2527 swap = !swap;
2528 }
2529
2530 // Store
2531 variant = shrink ? CanvasSdfShaderGLES3::MODE_STORE_SHRINK : CanvasSdfShaderGLES3::MODE_STORE;
2532 success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
2533 if (!success) {
2534 return;
2535 }
2536
2537 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);
2538 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);
2539 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);
2540 sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);
2541
2542 glBindTexture(GL_TEXTURE_2D, 0);
2543 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_read, 0);
2544 glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);
2545
2546 copy_effects->draw_screen_triangle();
2547
2548 glBindTexture(GL_TEXTURE_2D, 0);
2549 glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
2550 glDeleteFramebuffers(1, &temp_fb);
2551 glDisable(GL_SCISSOR_TEST);
2552}
2553
2554void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
2555 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2556 ERR_FAIL_NULL(rt);
2557 ERR_FAIL_COND(rt->direct_to_screen);
2558
2559 if (rt->backbuffer_fbo == 0) {
2560 _create_render_target_backbuffer(rt);
2561 }
2562
2563 Rect2i region;
2564 if (p_region == Rect2i()) {
2565 region.size = rt->size;
2566 } else {
2567 region = Rect2i(Size2i(), rt->size).intersection(p_region);
2568 if (region.size == Size2i()) {
2569 return; //nothing to do
2570 }
2571 }
2572
2573 glDisable(GL_BLEND);
2574 // Single texture copy for backbuffer.
2575 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
2576 glActiveTexture(GL_TEXTURE0);
2577 glBindTexture(GL_TEXTURE_2D, rt->color);
2578 GLES3::CopyEffects::get_singleton()->copy_screen();
2579
2580 if (p_gen_mipmaps) {
2581 GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);
2582 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
2583 }
2584
2585 glEnable(GL_BLEND); // 2D starts with blend enabled.
2586}
2587
2588void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
2589 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2590 ERR_FAIL_NULL(rt);
2591 ERR_FAIL_COND(rt->direct_to_screen);
2592
2593 if (rt->backbuffer_fbo == 0) {
2594 _create_render_target_backbuffer(rt);
2595 }
2596
2597 Rect2i region;
2598 if (p_region == Rect2i()) {
2599 // Just do a full screen clear;
2600 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
2601 glClearColor(p_color.r, p_color.g, p_color.b, p_color.a);
2602 glClear(GL_COLOR_BUFFER_BIT);
2603 } else {
2604 region = Rect2i(Size2i(), rt->size).intersection(p_region);
2605 if (region.size == Size2i()) {
2606 return; //nothing to do
2607 }
2608 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
2609 GLES3::CopyEffects::get_singleton()->set_color(p_color, region);
2610 }
2611}
2612
2613void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
2614 RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2615 ERR_FAIL_NULL(rt);
2616
2617 if (rt->backbuffer_fbo == 0) {
2618 _create_render_target_backbuffer(rt);
2619 }
2620
2621 Rect2i region;
2622 if (p_region == Rect2i()) {
2623 region.size = rt->size;
2624 } else {
2625 region = Rect2i(Size2i(), rt->size).intersection(p_region);
2626 if (region.size == Size2i()) {
2627 return; //nothing to do
2628 }
2629 }
2630 glDisable(GL_BLEND);
2631 GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);
2632 glEnable(GL_BLEND); // 2D starts with blend enabled.
2633
2634 glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
2635}
2636
2637#endif // GLES3_ENABLED
2638