CYD-UI
A C++ library for building native graphic user interfaces
Loading...
Searching...
No Matches
device_texture.cppm
Go to the documentation of this file.
1// Copyright (c) 2024, Víctor Castillo Agüero.
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4module;
5#include <cairomm-1.16/cairomm/cairomm.h>
6#include <tracy/Tracy.hpp>
7
8#define SDL_MAIN_HANDLED
9#include <SDL3/SDL.h>
10
11export module cydui.graphics:dev_texture;
12
13import std;
14
15import fabric.profiling;
16
19
20export namespace cydui::compositing {
22 using texture_ptr = SDL_Texture*;
23
24 device_texture_t(bool streaming = false): w(0), h(0), streaming_(streaming) {
25 }
26 device_texture_t(const device_texture_t &other): renderer_(other.renderer_), w(other.w), h(other.h), streaming_(other.streaming_) {
27 if (other.texture != nullptr) {
28 texture = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_BGRA32, streaming_? SDL_TEXTUREACCESS_STREAMING: SDL_TEXTUREACCESS_TARGET, w, h);
29 other.copy_into(renderer_, *this, nullptr);
30 }
31 }
33 this->renderer_ = other.renderer_;
34 this->w = other.w;
35 this->h = other.h;
36 this->streaming_ = other.streaming_;
37 if (other.texture != nullptr) {
38 texture = SDL_CreateTexture(renderer_, SDL_PIXELFORMAT_BGRA32, streaming_? SDL_TEXTUREACCESS_STREAMING: SDL_TEXTUREACCESS_TARGET, w, h);
39 other.copy_into(renderer_, *this, nullptr);
40 }
41 return *this;
42 }
43 device_texture_t(device_texture_t &&other) noexcept: renderer_(other.renderer_), w(other.w), h(other.h), streaming_(other.streaming_) {
44 if (other.texture != nullptr) {
45 texture = other.texture;
46 other.texture = nullptr;
47 }
48 }
50 this->renderer_ = other.renderer_;
51 this->w = other.w;
52 this->h = other.h;
53 this->streaming_ = other.streaming_;
54 if (other.texture != nullptr) {
55 texture = other.texture;
56 other.texture = nullptr;
57 }
58 return *this;
59 }
61 SDL_DestroyTexture(texture);
62 }
63
64 void resize(SDL_Renderer* renderer, float w, float h, bool copy_old = false) {
65 renderer_ = renderer;
66 if (w != this->w || h != this->h) {
67 ZoneScopedN("Resize Texture");
68 SDL_Texture* old_texture = texture;
69 texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_BGRA32, streaming_? SDL_TEXTUREACCESS_STREAMING: SDL_TEXTUREACCESS_TARGET, w, h);
70
71 if (old_texture != nullptr) {
72 if (copy_old) {
73 SDL_SetRenderTarget(renderer, texture);
74 SDL_SetTextureBlendMode(old_texture, SDL_BLENDMODE_BLEND);
75 SDL_FRect dst {
76 .x = 0,
77 .y = 0,
78 .w = std::min(w, this->w),
79 .h = std::min(h, this->h)
80 };
81 SDL_RenderTexture(renderer, old_texture, &dst, &dst);
82 SDL_SetRenderTarget(renderer, nullptr);
83 }
84 SDL_DestroyTexture(old_texture);
85 }
86
87 this->w = w;
88 this->h = h;
89 }
90 }
91
92 void clear(SDL_Renderer* renderer) {
93 renderer_ = renderer;
94 if (texture == nullptr) return;
95 ZoneScopedN("Clear Texture");
96 SDL_SetRenderTarget(renderer, texture);
97 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
98 SDL_RenderClear(renderer);
99 SDL_SetRenderTarget(renderer, nullptr);
100 }
101
102 void update_with(const pixelmap_t& pm) {
103 if (texture == nullptr) return;
104 ZoneScopedN("Update Texture");
105 // if (streaming_) {
106 // void* pixels = nullptr;
107 // int pitch;
108 // SDL_LockTexture(texture, nullptr, &pixels, &pitch);
109 // std::memcpy(pixels, pm.data, pm.height() * pm.width() * sizeof(pixel_t));
110 // SDL_UnlockTexture(texture);
111 // } else {
112 SDL_UpdateTexture(texture, nullptr, pm.data, pm.width() * sizeof(pixel_t));
113 // }
114 }
115
116 void* lock() {
117 if (texture == nullptr) return nullptr;
118 ZoneScopedN("Lock Texture");
119 void* pixels = nullptr;
120 int pitch;
121 locked_ = true;
122 SDL_LockTexture(texture, nullptr, &pixels, &pitch);
123 return pixels;
124 }
125
126 void unlock() {
127 if (texture == nullptr) return;
128 ZoneScopedN("Unlock Texture");
129 SDL_UnlockTexture(texture);
130 locked_ = false;
131 }
132
133 bool is_locked() const {
134 return locked_;
135 }
136
137 void copy_into(SDL_Renderer* renderer, device_texture_t& other, SDL_FRect* dst, bool blend = true, SDL_FRect* src_ = nullptr) {
138 renderer_ = renderer;
139 if (texture == nullptr) return;
140 ZoneScopedN("Copying Texture");
141 SDL_SetRenderTarget(renderer, other.texture);
142 if (blend) {
143 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
144 } else {
145 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_NONE);
146 }
147 SDL_FRect src {
148 .x = 0,
149 .y = 0,
150 .w = this->w,
151 .h = this->h
152 };
153 if (src_ != nullptr) {
154 src = *src_;
155 }
156
157 SDL_RenderTexture(renderer, texture, &src, dst);
158 SDL_SetRenderTarget(renderer, nullptr);
159 }
160
161 void copy_into(SDL_Renderer* renderer, device_texture_t& other, SDL_FRect* dst) const {
162 if (texture == nullptr) return;
163 ZoneScopedN("Copying Texture");
164 SDL_SetRenderTarget(renderer, other.texture);
165 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
166 SDL_FRect src {
167 .x = 0,
168 .y = 0,
169 .w = this->w,
170 .h = this->h
171 };
172 SDL_RenderTexture(renderer, texture, &src, dst);
173 SDL_SetRenderTarget(renderer, nullptr);
174 }
175
176 float width() const {
177 return w;
178 }
179 float height() const {
180 return h;
181 }
182
183 SDL_Texture* sdl_texture() {
184 return texture;
185 }
186
187 private:
188 [[refl::ignore]]
189 SDL_Renderer* renderer_ = nullptr;
190 texture_ptr texture {nullptr};
191 float w, h;
192 bool streaming_ = false;
193 bool locked_ = false;
194 };
195}
void update_with(const pixelmap_t &pm)
void clear(SDL_Renderer *renderer)
device_texture_t(device_texture_t &&other) noexcept
device_texture_t & operator=(const device_texture_t &other)
device_texture_t & operator=(device_texture_t &&other) noexcept
void copy_into(SDL_Renderer *renderer, device_texture_t &other, SDL_FRect *dst, bool blend=true, SDL_FRect *src_=nullptr)
void resize(SDL_Renderer *renderer, float w, float h, bool copy_old=false)
device_texture_t(const device_texture_t &other)
void copy_into(SDL_Renderer *renderer, device_texture_t &other, SDL_FRect *dst) const
size_t width() const
Definition pixelmap.cppm:25