Skip to content

Commit

Permalink
Optimize the case for generating GradientTexture2D with a solid color
Browse files Browse the repository at this point in the history
  • Loading branch information
Xrayez committed Dec 15, 2020
1 parent 3099971 commit c9ff44d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
45 changes: 28 additions & 17 deletions scene/resources/gradient_texture_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,37 @@ void GradientTexture2D::_update() {
if (gradient.is_null()) {
return;
}
PoolVector<uint8_t> data;
data.resize(width * height * 4);
{
PoolVector<uint8_t>::Write wd8 = data.write();
Gradient &g = **gradient;

for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float ofs = _get_gradient_offset_at(x, y);
Color color = g.get_color_at_offset(ofs);

wd8[(x + (y * width)) * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
wd8[(x + (y * width)) * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
wd8[(x + (y * width)) * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
wd8[(x + (y * width)) * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
Ref<Image> image;
image.instance();

if (gradient->get_points_count() <= 1) { // No need to interpolate.
image->create(width, height, false, Image::FORMAT_RGBA8);
Color color;
if (gradient->get_points_count() == 1) {
color = gradient->get_color(0);
} else {
color = Color(0, 0, 0, 1);
}
image->fill(color);
} else {
PoolVector<uint8_t> data;
data.resize(width * height * 4);
{
PoolVector<uint8_t>::Write wd8 = data.write();
Gradient &g = **gradient;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float ofs = _get_gradient_offset_at(x, y);
const Color &c = g.get_color_at_offset(ofs);
wd8[(x + (y * width)) * 4 + 0] = uint8_t(CLAMP(c.r * 255.0, 0, 255));
wd8[(x + (y * width)) * 4 + 1] = uint8_t(CLAMP(c.g * 255.0, 0, 255));
wd8[(x + (y * width)) * 4 + 2] = uint8_t(CLAMP(c.b * 255.0, 0, 255));
wd8[(x + (y * width)) * 4 + 3] = uint8_t(CLAMP(c.a * 255.0, 0, 255));
}
}
}
image->create(width, height, false, Image::FORMAT_RGBA8, data);
}
Ref<Image> image = memnew(Image(width, height, false, Image::FORMAT_RGBA8, data));

VS::get_singleton()->texture_allocate(texture, width, height, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, VS::TEXTURE_FLAG_FILTER);
VS::get_singleton()->texture_set_data(texture, image);

Expand Down
19 changes: 19 additions & 0 deletions tests/project/goost/scene/resources/test_gradient_texture_2d.gd
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
extends "res://addons/gut/test.gd"


func test_linear():
var texture = GradientTexture2D.new()
var gradient = Gradient.new()
Expand Down Expand Up @@ -33,3 +34,21 @@ func test_radial():
assert_eq(image.get_pixel(0, 0), Color.white)
assert_ne(image.get_pixel(texture.get_width() - 1, 0), Color.black)
image.unlock()


func test_gradient_single_color():
var texture = GradientTexture2D.new()
var gradient = Gradient.new()
for i in gradient.get_point_count():
gradient.remove_point(i)
texture.gradient = gradient

yield(texture, "changed")

var image = texture.get_data()
assert_not_null(image)

image.lock()
assert_eq(image.get_pixel(0, 0), Color.white)
assert_eq(image.get_pixel(texture.get_width() - 1, 0), Color.white)
image.unlock()

0 comments on commit c9ff44d

Please sign in to comment.