Merge pull request #477 from ShadelessFox/canvas-data-fix
Canvas: Reuse image data instead of fetching it every time off the GPU
This commit is contained in:
commit
bba66c33f2
@ -5,8 +5,9 @@
|
|||||||
#include "graphics/core/Texture.hpp"
|
#include "graphics/core/Texture.hpp"
|
||||||
|
|
||||||
gui::Canvas::Canvas(ImageFormat inFormat, glm::uvec2 inSize) : UINode(inSize) {
|
gui::Canvas::Canvas(ImageFormat inFormat, glm::uvec2 inSize) : UINode(inSize) {
|
||||||
ImageData data {inFormat, inSize.x, inSize.y};
|
auto data = std::make_shared<ImageData>(inFormat, inSize.x, inSize.y);
|
||||||
mTexture = Texture::from(&data);
|
mTexture = Texture::from(data.get());
|
||||||
|
mData = std::move(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui::Canvas::draw(const DrawContext& pctx, const Assets& assets) {
|
void gui::Canvas::draw(const DrawContext& pctx, const Assets& assets) {
|
||||||
|
|||||||
@ -15,11 +15,15 @@ namespace gui {
|
|||||||
|
|
||||||
void draw(const DrawContext& pctx, const Assets& assets) override;
|
void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<::Texture> texture() const {
|
[[nodiscard]] auto texture() const {
|
||||||
return mTexture;
|
return mTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] auto data() const {
|
||||||
|
return mData;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<::Texture> mTexture;
|
std::shared_ptr<::Texture> mTexture;
|
||||||
std::unique_ptr<ImageData> mData;
|
std::shared_ptr<ImageData> mData;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ static int p_get_src(UINode* node, lua::State* L) {
|
|||||||
|
|
||||||
static int p_get_data(UINode* node, lua::State* L) {
|
static int p_get_data(UINode* node, lua::State* L) {
|
||||||
if (auto canvas = dynamic_cast<Canvas*>(node)) {
|
if (auto canvas = dynamic_cast<Canvas*>(node)) {
|
||||||
return lua::newuserdata<lua::LuaCanvas>(L, canvas->texture());
|
return lua::newuserdata<lua::LuaCanvas>(L, canvas->texture(), canvas->data());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,22 +96,29 @@ namespace lua {
|
|||||||
|
|
||||||
class LuaCanvas : public Userdata {
|
class LuaCanvas : public Userdata {
|
||||||
public:
|
public:
|
||||||
explicit LuaCanvas(std::shared_ptr<Texture> inTexture);
|
explicit LuaCanvas(
|
||||||
|
std::shared_ptr<Texture> inTexture,
|
||||||
|
std::shared_ptr<ImageData> inData
|
||||||
|
);
|
||||||
~LuaCanvas() override = default;
|
~LuaCanvas() override = default;
|
||||||
|
|
||||||
const std::string& getTypeName() const override {
|
const std::string& getTypeName() const override {
|
||||||
return TYPENAME;
|
return TYPENAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] Texture& texture() const { return *mTexture; }
|
[[nodiscard]] auto& texture() const {
|
||||||
|
return *mTexture;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] ImageData& data() const { return *mData; }
|
[[nodiscard]] auto& data() const {
|
||||||
|
return *mData;
|
||||||
|
}
|
||||||
|
|
||||||
static int createMetatable(lua::State*);
|
static int createMetatable(lua::State*);
|
||||||
inline static std::string TYPENAME = "Canvas";
|
inline static std::string TYPENAME = "Canvas";
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Texture> mTexture;
|
std::shared_ptr<Texture> mTexture;
|
||||||
std::unique_ptr<ImageData> mData;
|
std::shared_ptr<ImageData> mData;
|
||||||
};
|
};
|
||||||
static_assert(!std::is_abstract<LuaCanvas>());
|
static_assert(!std::is_abstract<LuaCanvas>());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,17 @@
|
|||||||
|
|
||||||
using namespace lua;
|
using namespace lua;
|
||||||
|
|
||||||
LuaCanvas::LuaCanvas(std::shared_ptr<Texture> inTexture)
|
LuaCanvas::LuaCanvas(
|
||||||
: mTexture(std::move(inTexture)) {
|
std::shared_ptr<Texture> inTexture, std::shared_ptr<ImageData> inData
|
||||||
mData = mTexture->readData();
|
)
|
||||||
|
: mTexture(std::move(inTexture)), mData(std::move(inData)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
union RGBA {
|
union RGBA {
|
||||||
uint8_t rgba[4];
|
struct {
|
||||||
uint32_t raw;
|
uint8_t r, g, b, a;
|
||||||
|
};
|
||||||
|
uint32_t rgba;
|
||||||
};
|
};
|
||||||
|
|
||||||
static RGBA* get_at(const ImageData& data, uint index) {
|
static RGBA* get_at(const ImageData& data, uint index) {
|
||||||
@ -29,8 +32,8 @@ static RGBA* get_at(const ImageData& data, uint x, uint y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static RGBA* get_at(State* L, uint x, uint y) {
|
static RGBA* get_at(State* L, uint x, uint y) {
|
||||||
if (auto texture = touserdata<LuaCanvas>(L, 1)) {
|
if (auto canvas = touserdata<LuaCanvas>(L, 1)) {
|
||||||
return get_at(texture->data(), x, y);
|
return get_at(canvas->data(), x, y);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -40,7 +43,7 @@ static int l_at(State* L) {
|
|||||||
auto y = static_cast<uint>(tointeger(L, 3));
|
auto y = static_cast<uint>(tointeger(L, 3));
|
||||||
|
|
||||||
if (auto pixel = get_at(L, x, y)) {
|
if (auto pixel = get_at(L, x, y)) {
|
||||||
return pushinteger(L, pixel->raw);
|
return pushinteger(L, pixel->rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -53,19 +56,19 @@ static int l_set(State* L) {
|
|||||||
if (auto pixel = get_at(L, x, y)) {
|
if (auto pixel = get_at(L, x, y)) {
|
||||||
switch (gettop(L)) {
|
switch (gettop(L)) {
|
||||||
case 4:
|
case 4:
|
||||||
pixel->raw = static_cast<uint>(tointeger(L, 4));
|
pixel->rgba = static_cast<uint>(tointeger(L, 4));
|
||||||
return 1;
|
return 1;
|
||||||
case 6:
|
case 6:
|
||||||
pixel->rgba[0] = static_cast<ubyte>(tointeger(L, 4));
|
pixel->r = static_cast<ubyte>(tointeger(L, 4));
|
||||||
pixel->rgba[1] = static_cast<ubyte>(tointeger(L, 5));
|
pixel->g = static_cast<ubyte>(tointeger(L, 5));
|
||||||
pixel->rgba[2] = static_cast<ubyte>(tointeger(L, 6));
|
pixel->b = static_cast<ubyte>(tointeger(L, 6));
|
||||||
pixel->rgba[3] = 255;
|
pixel->a = 255;
|
||||||
return 1;
|
return 1;
|
||||||
case 7:
|
case 7:
|
||||||
pixel->rgba[0] = static_cast<ubyte>(tointeger(L, 4));
|
pixel->r = static_cast<ubyte>(tointeger(L, 4));
|
||||||
pixel->rgba[1] = static_cast<ubyte>(tointeger(L, 5));
|
pixel->g = static_cast<ubyte>(tointeger(L, 5));
|
||||||
pixel->rgba[2] = static_cast<ubyte>(tointeger(L, 6));
|
pixel->b = static_cast<ubyte>(tointeger(L, 6));
|
||||||
pixel->rgba[3] = static_cast<ubyte>(tointeger(L, 7));
|
pixel->a = static_cast<ubyte>(tointeger(L, 7));
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -76,8 +79,8 @@ static int l_set(State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_update(State* L) {
|
static int l_update(State* L) {
|
||||||
if (auto texture = touserdata<LuaCanvas>(L, 1)) {
|
if (auto canvas = touserdata<LuaCanvas>(L, 1)) {
|
||||||
texture->texture().reload(texture->data());
|
canvas->texture().reload(canvas->data());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -96,7 +99,7 @@ static int l_meta_index(State* L) {
|
|||||||
auto& data = texture->data();
|
auto& data = texture->data();
|
||||||
if (isnumber(L, 2)) {
|
if (isnumber(L, 2)) {
|
||||||
if (auto pixel = get_at(data, static_cast<uint>(tointeger(L, 2)))) {
|
if (auto pixel = get_at(data, static_cast<uint>(tointeger(L, 2)))) {
|
||||||
return pushinteger(L, pixel->raw);
|
return pushinteger(L, pixel->rgba);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isstring(L, 2)) {
|
if (isstring(L, 2)) {
|
||||||
@ -122,7 +125,7 @@ static int l_meta_newindex(State* L) {
|
|||||||
auto& data = texture->data();
|
auto& data = texture->data();
|
||||||
if (isnumber(L, 2) && isnumber(L, 3)) {
|
if (isnumber(L, 2) && isnumber(L, 3)) {
|
||||||
if (auto pixel = get_at(data, static_cast<uint>(tointeger(L, 2)))) {
|
if (auto pixel = get_at(data, static_cast<uint>(tointeger(L, 2)))) {
|
||||||
pixel->raw = static_cast<uint>(tointeger(L, 3));
|
pixel->rgba = static_cast<uint>(tointeger(L, 3));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user