summaryrefslogtreecommitdiff
path: root/modules/pvr/texture_loader_pvr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/pvr/texture_loader_pvr.cpp')
-rw-r--r--modules/pvr/texture_loader_pvr.cpp156
1 files changed, 55 insertions, 101 deletions
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index a8e8a9a2f1..83f032ca2b 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,16 +29,12 @@
/*************************************************************************/
#include "texture_loader_pvr.h"
-#include "PvrTcEncoder.h"
-#include "RgbaBitmap.h"
+
#include "core/os/file_access.h"
-#include <string.h>
-#include <new>
static void _pvrtc_decompress(Image *p_img);
enum PVRFLags {
-
PVR_HAS_MIPMAPS = 0x00000100,
PVR_TWIDDLED = 0x00000200,
PVR_NORMAL_MAP = 0x00000400,
@@ -48,25 +44,26 @@ enum PVRFLags {
PVR_VOLUME_TEXTURES = 0x00004000,
PVR_HAS_ALPHA = 0x00008000,
PVR_VFLIP = 0x00010000
-
};
-RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
-
- if (r_error)
+RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (!f)
+ if (!f) {
return RES();
+ }
FileAccessRef faref(f);
ERR_FAIL_COND_V(err, RES());
- if (r_error)
+ if (r_error) {
*r_error = ERR_FILE_CORRUPT;
+ }
uint32_t hsize = f->get_32();
@@ -109,11 +106,14 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
Image::Format format = Image::FORMAT_MAX;
switch (flags & 0xFF) {
-
case 0x18:
- case 0xC: format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC2A : Image::FORMAT_PVRTC2; break;
+ case 0xC:
+ format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC1_2A : Image::FORMAT_PVRTC1_2;
+ break;
case 0x19:
- case 0xD: format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4; break;
+ case 0xD:
+ format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC1_4A : Image::FORMAT_PVRTC1_4;
+ break;
case 0x16:
format = Image::FORMAT_L8;
break;
@@ -153,79 +153,35 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
}
Ref<Image> image = memnew(Image(width, height, mipmaps, format, data));
- ERR_FAIL_COND_V(image->empty(), RES());
+ ERR_FAIL_COND_V(image->is_empty(), RES());
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(image);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return texture;
}
void ResourceFormatPVR::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("pvr");
}
-bool ResourceFormatPVR::handles_type(const String &p_type) const {
+bool ResourceFormatPVR::handles_type(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Texture2D");
}
-String ResourceFormatPVR::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "pvr")
+String ResourceFormatPVR::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "pvr") {
return "Texture2D";
- return "";
-}
-
-static void _compress_pvrtc4(Image *p_img) {
-
- Ref<Image> img = p_img->duplicate();
-
- bool make_mipmaps = false;
- if (!img->is_size_po2() || img->get_width() != img->get_height()) {
- make_mipmaps = img->has_mipmaps();
- img->resize_to_po2(true);
}
- img->convert(Image::FORMAT_RGBA8);
- if (!img->has_mipmaps() && make_mipmaps)
- img->generate_mipmaps();
-
- bool use_alpha = img->detect_alpha();
-
- Ref<Image> new_img;
- new_img.instance();
- new_img->create(img->get_width(), img->get_height(), img->has_mipmaps(), use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4);
-
- Vector<uint8_t> data = new_img->get_data();
- {
- uint8_t *wr = data.ptrw();
- const uint8_t *r = img->get_data().ptr();
-
- for (int i = 0; i <= new_img->get_mipmap_count(); i++) {
-
- int ofs, size, w, h;
- img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
- Javelin::RgbaBitmap bm(w, h);
- for (int j = 0; j < size / 4; j++) {
- Javelin::ColorRgba<unsigned char> *dp = bm.GetData();
- /* red and Green colors are swapped. */
- new (dp) Javelin::ColorRgba<unsigned char>(r[ofs + 4 * j + 2], r[ofs + 4 * j + 1], r[ofs + 4 * j], r[ofs + 4 * j + 3]);
- }
- new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
- Javelin::PvrTcEncoder::EncodeRgba4Bpp(&wr[ofs], bm);
- }
- }
-
- p_img->create(new_img->get_width(), new_img->get_height(), new_img->has_mipmaps(), new_img->get_format(), data);
+ return "";
}
ResourceFormatPVR::ResourceFormatPVR() {
-
Image::_image_decompress_pvrtc = _pvrtc_decompress;
- Image::_image_compress_pvrtc4_func = _compress_pvrtc4;
- Image::_image_compress_pvrtc2_func = _compress_pvrtc4;
}
/////////////////////////////////////////////////////////
@@ -251,35 +207,32 @@ ResourceFormatPVR::ResourceFormatPVR() {
struct PVRTCBlock {
//blocks are 64 bits
- uint32_t data[2];
+ uint32_t data[2] = {};
};
_FORCE_INLINE_ bool is_po2(uint32_t p_input) {
-
- if (p_input == 0)
- return 0;
+ if (p_input == 0) {
+ return false;
+ }
uint32_t minus1 = p_input - 1;
- return ((p_input | minus1) == (p_input ^ minus1)) ? 1 : 0;
+ return ((p_input | minus1) == (p_input ^ minus1)) ? true : false;
}
static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) {
-
uint32_t raw_bits[2];
raw_bits[0] = p_block->data[1] & (0xFFFE);
raw_bits[1] = p_block->data[1] >> 16;
for (int i = 0; i < 2; i++) {
-
if (raw_bits[i] & (1 << 15)) {
-
p_ab_colors[i][0] = (raw_bits[i] >> 10) & 0x1F;
p_ab_colors[i][1] = (raw_bits[i] >> 5) & 0x1F;
p_ab_colors[i][2] = raw_bits[i] & 0x1F;
- if (i == 0)
+ if (i == 0) {
p_ab_colors[0][2] |= p_ab_colors[0][2] >> 4;
+ }
p_ab_colors[i][3] = 0xF;
} else {
-
p_ab_colors[i][0] = (raw_bits[i] >> (8 - 1)) & 0x1E;
p_ab_colors[i][1] = (raw_bits[i] >> (4 - 1)) & 0x1E;
@@ -288,10 +241,11 @@ static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) {
p_ab_colors[i][2] = (raw_bits[i] & 0xF) << 1;
- if (i == 0)
+ if (i == 0) {
p_ab_colors[0][2] |= p_ab_colors[0][2] >> 3;
- else
+ } else {
p_ab_colors[0][2] |= p_ab_colors[0][2] >> 4;
+ }
p_ab_colors[i][3] = (raw_bits[i] >> 11) & 0xE;
}
@@ -299,15 +253,12 @@ static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) {
}
static void unpack_modulations(const PVRTCBlock *p_block, const int p_2bit, int p_modulation[8][16], int p_modulation_modes[8][16], int p_x, int p_y) {
-
int block_mod_mode = p_block->data[1] & 1;
uint32_t modulation_bits = p_block->data[0];
if (p_2bit && block_mod_mode) {
-
for (int y = 0; y < BLK_Y_SIZE; y++) {
for (int x = 0; x < BLK_X_2BPP; x++) {
-
p_modulation_modes[y + p_y][x + p_x] = block_mod_mode;
if (((x ^ y) & 1) == 0) {
@@ -318,15 +269,15 @@ static void unpack_modulations(const PVRTCBlock *p_block, const int p_2bit, int
}
} else if (p_2bit) {
-
for (int y = 0; y < BLK_Y_SIZE; y++) {
for (int x = 0; x < BLK_X_2BPP; x++) {
p_modulation_modes[y + p_y][x + p_x] = block_mod_mode;
- if (modulation_bits & 1)
+ if (modulation_bits & 1) {
p_modulation[y + p_y][x + p_x] = 0x3;
- else
+ } else {
p_modulation[y + p_y][x + p_x] = 0x0;
+ }
modulation_bits >>= 1;
}
@@ -361,10 +312,11 @@ static void interpolate_colors(const int p_colorp[4], const int p_colorq[4], con
v = (y & 0x3) | ((~y & 0x2) << 1);
- if (p_2bit)
+ if (p_2bit) {
u = (x & 0x7) | ((~x & 0x4) << 1);
- else
+ } else {
u = (x & 0x3) | ((~x & 0x2) << 1);
+ }
v = v - BLK_Y_SIZE / 2;
@@ -420,19 +372,20 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod
y = (y & 0x3) | ((~y & 0x2) << 1);
- if (p_2bit)
+ if (p_2bit) {
x = (x & 0x7) | ((~x & 0x4) << 1);
- else
+ } else {
x = (x & 0x3) | ((~x & 0x2) << 1);
+ }
*p_dopt = 0;
if (p_modulation_modes[y][x] == 0) {
mod_val = rep_vals0[p_modulation[y][x]];
} else if (p_2bit) {
- if (((x ^ y) & 1) == 0)
+ if (((x ^ y) & 1) == 0) {
mod_val = rep_vals0[p_modulation[y][x]];
- else if (p_modulation_modes[y][x] == 1) {
+ } else if (p_modulation_modes[y][x] == 1) {
mod_val = (rep_vals0[p_modulation[y - 1][x]] +
rep_vals0[p_modulation[y + 1][x]] +
rep_vals0[p_modulation[y][x - 1]] +
@@ -459,7 +412,6 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod
static int disable_twiddling = 0;
static uint32_t twiddle_uv(uint32_t p_height, uint32_t p_width, uint32_t p_y, uint32_t p_x) {
-
uint32_t twiddled;
uint32_t min_dimension;
@@ -484,8 +436,9 @@ static uint32_t twiddle_uv(uint32_t p_height, uint32_t p_width, uint32_t p_y, ui
max_value = p_y;
}
- if (disable_twiddling)
+ if (disable_twiddling) {
return (p_y * p_width + p_x);
+ }
scr_bit_pos = 1;
dst_bit_pos = 1;
@@ -545,17 +498,17 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
int r_result[4];
- if (p_2bit)
+ if (p_2bit) {
x_block_size = BLK_X_2BPP;
- else
+ } else {
x_block_size = BLK_X_4BPP;
+ }
block_width = MAX(2, p_width / x_block_size);
block_height = MAX(2, p_height / BLK_Y_SIZE);
for (y = 0; y < p_height; y++) {
for (x = 0; x < p_width; x++) {
-
block_x = (x - x_block_size / 2);
blk_y = (y - BLK_Y_SIZE / 2);
@@ -620,8 +573,9 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
r_result[i] >>= 3;
}
- if (DoPT)
+ if (DoPT) {
r_result[3] = 0;
+ }
u_pos = (x + y * p_width) << 2;
p_dst[u_pos + 0] = (uint8_t)r_result[0];
@@ -633,10 +587,9 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
}
static void _pvrtc_decompress(Image *p_img) {
+ ERR_FAIL_COND(p_img->get_format() != Image::FORMAT_PVRTC1_2 && p_img->get_format() != Image::FORMAT_PVRTC1_2A && p_img->get_format() != Image::FORMAT_PVRTC1_4 && p_img->get_format() != Image::FORMAT_PVRTC1_4A);
- ERR_FAIL_COND(p_img->get_format() != Image::FORMAT_PVRTC2 && p_img->get_format() != Image::FORMAT_PVRTC2A && p_img->get_format() != Image::FORMAT_PVRTC4 && p_img->get_format() != Image::FORMAT_PVRTC4A);
-
- bool _2bit = (p_img->get_format() == Image::FORMAT_PVRTC2 || p_img->get_format() == Image::FORMAT_PVRTC2A);
+ bool _2bit = (p_img->get_format() == Image::FORMAT_PVRTC1_2 || p_img->get_format() == Image::FORMAT_PVRTC1_2A);
Vector<uint8_t> data = p_img->get_data();
const uint8_t *r = data.ptr();
@@ -649,6 +602,7 @@ static void _pvrtc_decompress(Image *p_img) {
bool make_mipmaps = p_img->has_mipmaps();
p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
- if (make_mipmaps)
+ if (make_mipmaps) {
p_img->generate_mipmaps();
+ }
}