16KHASH_MAP_INIT_INT64(dttr_surface_texture_cache,
DTTR_Texture)
31static khash_t(dttr_surface_texture_cache) * surface_texture_cache;
45 if (!width || !height || width > (uint32_t)INT_MAX || height > (uint32_t)INT_MAX) {
49 if ((
size_t)width > SIZE_MAX / (
size_t)height /
sizeof(uint32_t)) {
53 const size_t size = (size_t)width * (
size_t)height *
sizeof(uint32_t);
54 if (
size == 0 ||
size > UINT32_MAX) {
70 size_t *out_pixel_size
80 if (!width || !height || (
bpp != 16u &&
bpp != 32u)) {
81 return DDERR_INVALIDPARAMS;
84 const uint64_t pitch_bits = (uint64_t)width * (uint64_t)
bpp;
85 const uint64_t pitch = (pitch_bits + 7u) / 8u;
86 if (pitch == 0 || pitch > UINT32_MAX || pitch > SIZE_MAX / height) {
87 return DDERR_INVALIDPARAMS;
91 return DDERR_INVALIDPARAMS;
95 *out_pitch = (uint32_t)pitch;
99 *out_pixel_size = (size_t)pitch * (
size_t)height;
112 return DDERR_INVALIDPARAMS;
116 *out = (
blit_rect){0, 0, default_w, default_h};
122 return DDERR_INVALIDRECT;
126 .x = (uint32_t)
rect->left,
127 .y = (uint32_t)
rect->top,
128 .w = (uint32_t)(
rect->right -
rect->left),
129 .h = (uint32_t)(
rect->bottom -
rect->top),
141 ||
rect->y >= surface_h) {
145 const uint32_t max_w = surface_w -
rect->x;
146 const uint32_t max_h = surface_h -
rect->y;
147 if (
rect->w > max_w) {
151 if (
rect->h > max_h) {
155 return rect->w != 0 &&
rect->h != 0;
159 if (!surface_texture_cache) {
163 kh_destroy(dttr_surface_texture_cache, surface_texture_cache);
164 surface_texture_cache =
NULL;
168 if (surface_texture_cache) {
172 surface_texture_cache = kh_init(dttr_surface_texture_cache);
173 return surface_texture_cache !=
NULL;
183 it = kh_put(dttr_surface_texture_cache, surface_texture_cache, key, &put_ret);
184 if (it == kh_end(surface_texture_cache)) {
188 kh_value(surface_texture_cache, it) = tex;
192 if (!surface_texture_cache || !key || !tex) {
196 const khint_t it = kh_get(dttr_surface_texture_cache, surface_texture_cache, key);
197 if (it == kh_end(surface_texture_cache)) {
201 if (kh_value(surface_texture_cache, it) == tex) {
202 kh_del(dttr_surface_texture_cache, surface_texture_cache, it);
207 if (!surface_texture_cache || !key) {
211 const khint_t it = kh_get(dttr_surface_texture_cache, surface_texture_cache, key);
212 if (it == kh_end(surface_texture_cache)) {
216 const DTTR_Texture tex = kh_value(surface_texture_cache, it);
217 const int idx = (int)tex - 1;
218 if (idx < 0 || idx >=
dttr_backend.staged_texture_count) {
219 kh_del(dttr_surface_texture_cache, surface_texture_cache, it);
224 if (
st->refcount == 0) {
225 kh_del(dttr_surface_texture_cache, surface_texture_cache, it);
239 .source_hash = source_hash,
243 .r_mask =
self->r_mask,
244 .g_mask =
self->g_mask,
245 .b_mask =
self->b_mask,
246 .a_mask =
self->a_mask,
247 .colorkey =
self->colorkey,
248 .has_colorkey =
self->has_colorkey ? 1 : 0,
251 return XXH3_64bits(&seed,
sizeof(seed));
258 memset(pf, 0,
sizeof(*pf));
259 pf->dwSize =
sizeof(*pf);
260 pf->dwFlags = DDPF_RGB | (
self->a_mask ? DDPF_ALPHAPIXELS : 0);
262 pf->dwRGBBitCount =
self->bpp;
263 pf->dwRBitMask =
self->r_mask;
264 pf->dwGBitMask =
self->g_mask;
265 pf->dwBBitMask =
self->b_mask;
266 pf->dwRGBAlphaBitMask =
self->a_mask;
271 const uint16_t *restrict
src,
272 uint32_t *restrict
dst,
277 for (uint32_t
y = 0;
y <
h;
y++) {
278 const uint16_t *row = (
const uint16_t *)((
const uint8_t *)
src +
y * src_pitch);
279 for (uint32_t
x = 0;
x <
w;
x++) {
280 uint16_t px = row[
x];
282 uint8_t a = (px >> 12) & 0xF;
284 uint8_t
r = (px >> 8) & 0xF;
286 uint8_t g = (px >> 4) & 0xF;
288 uint8_t b = px & 0xF;
290 dst[
y *
w +
x] = ((uint32_t)a << 24) | ((uint32_t)
r << 16)
291 | ((uint32_t)g << 8) | b;
298 const uint16_t *restrict
src,
299 uint32_t *restrict
dst,
306 for (uint32_t
y = 0;
y <
h;
y++) {
307 const uint16_t *row = (
const uint16_t *)((
const uint8_t *)
src +
y * src_pitch);
308 for (uint32_t
x = 0;
x <
w;
x++) {
309 uint16_t px = row[
x];
310 if (px == 0x0000 || (has_colorkey && px == colorkey)) {
311 dst[
y *
w +
x] = 0x00000000;
315 uint8_t
r = (px >> 11) & 0x1F;
316 r = (
r << 3) | (
r >> 2);
317 uint8_t g = (px >> 5) & 0x3F;
318 g = (g << 2) | (g >> 4);
319 uint8_t b = px & 0x1F;
320 b = (b << 3) | (b >> 2);
321 dst[
y *
w +
x] = 0xFF000000 | ((uint32_t)
r << 16) | ((uint32_t)g << 8) | b;
334 if (
self->convert_rgba &&
self->convert_rgba_capacity >=
size) {
335 return (uint32_t *)
self->convert_rgba;
338 void *resized = realloc(
self->convert_rgba,
size);
343 self->convert_rgba = resized;
345 return (uint32_t *)
self->convert_rgba;
353 if (!
self || !
self->pixels || upload_w == 0 || upload_h == 0) {
357 const uint32_t bytes_per_pixel =
self->bpp / 8;
358 const size_t row_bytes = (size_t)upload_w * bytes_per_pixel;
359 const uint8_t has_colorkey =
self->has_colorkey ? 1 : 0;
360 XXH3_state_t hash_state;
361 if (XXH3_64bits_reset(&hash_state) != XXH_OK) {
365 XXH3_64bits_update(&hash_state, &
self->bpp,
sizeof(
self->bpp));
366 XXH3_64bits_update(&hash_state, &
self->a_mask,
sizeof(
self->a_mask));
367 XXH3_64bits_update(&hash_state, &has_colorkey,
sizeof(has_colorkey));
368 XXH3_64bits_update(&hash_state, &
self->colorkey,
sizeof(
self->colorkey));
369 for (uint32_t
y = 0;
y < upload_h;
y++) {
370 const uint8_t *row = (
const uint8_t *)
self->pixels + (
size_t)
y *
self->pitch;
371 XXH3_64bits_update(&hash_state, row, row_bytes);
374 return XXH3_64bits_digest(&hash_state);
378 if (!
state || idx < 0 || idx >=
state->staged_texture_count) {
383 if (
st->pending_upload) {
387 st->pending_upload =
true;
388 kv_push(
int,
state->pending_upload_indices, idx);
397 const int idx = (int)tex - 1;
398 if (idx < 0 || idx >=
state->staged_texture_count) {
403 SDL_LockMutex(
state->texture_mutex);
404 refs =
state->staged_textures[idx].refcount;
405 SDL_UnlockMutex(
state->texture_mutex);
416 const int idx = (int)tex - 1;
417 if (idx < 0 || idx >=
state->staged_texture_count) {
421 bool retained =
false;
422 SDL_LockMutex(
state->texture_mutex);
424 if (
st->refcount > 0) {
429 SDL_UnlockMutex(
state->texture_mutex);
442 if (width <= 0 || height <= 0
447 SDL_LockMutex(
state->texture_mutex);
450 const int cached_idx = (int)cached_tex - 1;
453 SDL_UnlockMutex(
state->texture_mutex);
458 for (
int i = 0; i <
state->staged_texture_count; i++) {
459 if (
state->staged_textures[i].refcount != 0) {
463 if (
state->staged_textures[i].gpu_tex !=
NULL) {
473 SDL_UnlockMutex(
state->texture_mutex);
478 idx =
state->staged_texture_count++;
485 st->pending_upload =
false;
486 st->last_update_frame =
state->frame_index;
487 st->update_streak = 1;
489 st->cache_key_valid = cache_key != 0;
490 st->cache_key = cache_key;
492 const bool is_new_slot = (idx ==
state->staged_texture_count - 1);
493 st->pixels = malloc(
size);
497 state->staged_texture_count--;
500 SDL_UnlockMutex(
state->texture_mutex);
505 memcpy(
st->pixels, pixels,
size);
507 memset(
st->pixels, 0,
size);
510 if (
st->cache_key_valid) {
516 SDL_UnlockMutex(
state->texture_mutex);
527 const int idx = (int)tex - 1;
528 if (idx < 0 || idx >=
state->staged_texture_count) {
532 SDL_LockMutex(
state->texture_mutex);
534 if (
st->refcount > 1) {
536 SDL_UnlockMutex(
state->texture_mutex);
540 if (
st->refcount == 0) {
541 SDL_UnlockMutex(
state->texture_mutex);
546 if (
st->cache_key_valid) {
548 st->cache_key_valid =
false;
552 if (
state->bound_texture ==
st->gpu_tex) {
557 state->renderer->defer_texture_destroy(
state, idx);
561 st->pending_upload =
false;
564 st->last_update_frame = 0;
565 st->update_streak = 0;
566 SDL_UnlockMutex(
state->texture_mutex);
580 if (!tex || !pixels || width <= 0 || height <= 0
585 const int idx = (int)tex - 1;
586 if (idx < 0 || idx >=
state->staged_texture_count) {
590 bool updated =
false;
591 SDL_LockMutex(
state->texture_mutex);
593 if (
st->refcount != 1) {
594 SDL_UnlockMutex(
state->texture_mutex);
598 const bool had_cache_key =
st->cache_key_valid;
599 const uint64_t old_cache_key =
st->cache_key;
604 void *resized = realloc(
st->pixels,
size);
610 SDL_UnlockMutex(
state->texture_mutex);
614 const uint64_t current_frame =
state->frame_index;
615 if (current_frame <= st->last_update_frame + 1) {
618 st->update_streak = 1;
621 st->last_update_frame = current_frame;
623 st->pixels = resized;
624 memcpy(
st->pixels, pixels,
size);
625 if (
st->width != width ||
st->height != height) {
626 state->renderer->defer_texture_destroy(
state, idx);
632 st->cache_key = cache_key;
633 st->cache_key_valid = cache_key != 0;
634 if (
st->cache_key_valid) {
641 SDL_UnlockMutex(
state->texture_mutex);
654 if (!
self->pixels ||
self->width == 0 ||
self->height == 0) {
658 const uint32_t upload_w =
self->content_width ?
self->content_width :
self->width;
659 const uint32_t upload_h =
self->content_height ?
self->content_height :
self->height;
665 &&
self->last_upload_width == upload_w &&
self->last_upload_height == upload_h
666 &&
self->last_upload_hash == source_hash) {
671 uint32_t *converted =
NULL;
673 if (
self->bpp == 16) {
674 size_t converted_size = 0;
684 if (
self->a_mask == 0xF000) {
687 (
const uint16_t *)
self->pixels,
696 (
const uint16_t *)
self->pixels,
707 converted = (uint32_t *)
self->pixels;
710 const void *upload_data = converted;
712 bool upload_ok =
false;
739 self->last_upload_valid =
true;
740 self->last_upload_width = upload_w;
741 self->last_upload_height = upload_h;
742 self->last_upload_hash = source_hash;
745 self->dirty = !upload_ok;
754 const GUID *iid = (
const GUID *)riid;
761 return E_NOINTERFACE;
765 if (memcmp(iid, &IID_IDirect3DTexture2,
sizeof(GUID)) == 0) {
767 if (!
self->texture) {
772 *ppv =
self->texture;
779 if (memcmp(iid, &IID_IDirectDrawSurface7,
sizeof(GUID)) == 0
780 || memcmp(iid, &IID_IUnknown,
sizeof(GUID)) == 0) {
793 return E_NOINTERFACE;
797 return ++
self->refcount;
801 ULONG rc = --
self->refcount;
807 if (
self->dttr_texture) {
809 self->dttr_texture = 0;
812 if (
self->back_buffer) {
813 self->back_buffer->vtbl->Release(
self->back_buffer);
821 self->convert_rgba_capacity = 0;
830 ddrawsurface7_addattachedsurface,
836 ddrawsurface7_addoverlaydirtyrect,
852 if ((
flags & DDBLT_COLORFILL)) {
862 const uint32_t
bpp =
src->bpp / 8;
863 if (
bpp != 2u &&
bpp != 4u) {
864 return DDERR_INVALIDPARAMS;
874 if (rect_result !=
S_OK) {
880 (
const RECT *)dstRect,
885 if (rect_result !=
S_OK) {
899 if (!src_visible || !dst_visible) {
905 needs_scale = (src_region.w > dst_region.w || src_region.h > dst_region.h);
908 const uint32_t out_w = dst_region.w;
909 const uint32_t out_h = dst_region.h;
911 for (uint32_t
y = 0;
y < out_h;
y++) {
912 const uint32_t src_y = src_region.y + (
y * src_region.h) / out_h;
913 const uint8_t *src_row = (
const uint8_t *)
src->pixels
914 + src_y *
src->pitch;
915 uint8_t *dst_row = (uint8_t *)
self->pixels
916 + (dst_region.y +
y) *
self->pitch;
917 for (uint32_t
x = 0;
x < out_w;
x++) {
918 const uint32_t src_x = src_region.x + (
x * src_region.w) / out_w;
920 dst_row + (dst_region.x +
x) *
bpp,
921 src_row + src_x *
bpp,
927 self->content_width = dst_region.x + out_w;
928 self->content_height = dst_region.y + out_h;
930 uint32_t copy_w = src_region.w;
931 uint32_t copy_h = src_region.h;
932 if (copy_w > dst_region.w) {
933 copy_w = dst_region.w;
936 if (copy_h > dst_region.h) {
937 copy_h = dst_region.h;
940 if (copy_w == 0 || copy_h == 0) {
944 for (uint32_t
y = 0;
y < copy_h;
y++) {
945 const uint8_t *src_row = (
const uint8_t *)
src->pixels
946 + (src_region.y +
y) *
src->pitch
947 + src_region.x *
bpp;
948 uint8_t *dst_row = (uint8_t *)
self->pixels
949 + (dst_region.y +
y) *
self->pitch
950 + dst_region.x *
bpp;
951 memcpy(dst_row, src_row, copy_w *
bpp);
954 self->content_width = dst_region.x + copy_w;
955 self->content_height = dst_region.y + copy_h;
961 if (
self->dttr_texture !=
src->dttr_texture) {
968 self->dttr_texture =
src->dttr_texture;
978 ddrawsurface7_bltbatch,
986 ddrawsurface7_bltfast,
996 ddrawsurface7_deleteattachedsurface,
1003 ddrawsurface7_enumattachedsurfaces,
1010 ddrawsurface7_enumoverlayzorders,
1017static HRESULT __stdcall ddrawsurface7_flip(
1039 if (
self->back_buffer) {
1040 *surf =
self->back_buffer;
1051 *surf =
self->back_buffer;
1058 ddrawsurface7_getbltstatus,
1064 ddrawsurface7_getcaps,
1071 ddrawsurface7_getclipper,
1077static HRESULT __stdcall ddrawsurface7_getcolorkey(
1083 DDCOLORKEY *ck = (DDCOLORKEY *)
colorKey;
1084 ck->dwColorSpaceLowValue =
self->has_colorkey ?
self->colorkey : 0;
1085 ck->dwColorSpaceHighValue = ck->dwColorSpaceLowValue;
1092 ddrawsurface7_getdc,
1099 ddrawsurface7_getflipstatus,
1121 ddrawsurface7_getpalette,
1127static HRESULT __stdcall ddrawsurface7_getpixelformat(
1136 DDPIXELFORMAT *pf = (DDPIXELFORMAT *)
fmt;
1147 d->dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT;
1148 d->dwHeight =
self->height;
1149 d->dwWidth =
self->width;
1150 d->lPitch =
self->pitch;
1163 DDSURFACEDESC2 *
d = (DDSURFACEDESC2 *)
desc;
1167 memset((
char *)
desc + 4, 0,
size - 4);
1169 }
else if (
size == 0) {
1179 ddrawsurface7_initialize,
1187static HRESULT __stdcall ddrawsurface7_lock(
1195 if (!
self->pixels) {
1199 self->locked =
true;
1205 DDSURFACEDESC2 *
d = (DDSURFACEDESC2 *)
desc;
1210 memset((
char *)
desc + 4, 0,
size - 4);
1214 d->lpSurface =
self->pixels;
1215 d->dwFlags |= DDSD_LPSURFACE;
1216 }
else if (
size == 0) {
1220 d->dwFlags = DDSD_LPSURFACE | DDSD_PITCH;
1221 d->lPitch =
self->pitch;
1222 d->lpSurface =
self->pixels;
1229 ddrawsurface7_releasedc,
1237 ddrawsurface7_setclipper,
1248 const DDCOLORKEY *ck = (
const DDCOLORKEY *)
colorKey;
1249 self->has_colorkey =
true;
1250 self->colorkey = (uint16_t)ck->dwColorSpaceLowValue;
1251 self->last_upload_valid =
false;
1260 ddrawsurface7_setoverlayposition,
1267 ddrawsurface7_setpalette,
1277 if (!
self->locked) {
1281 self->locked =
false;
1291 ddrawsurface7_updateoverlay,
1301 ddrawsurface7_updateoverlaydisplay,
1307 ddrawsurface7_updateoverlayzorder,
1314 ddrawsurface7_getddinterface,
1321 ddrawsurface7_pagelock,
1327 ddrawsurface7_pageunlock,
1333 ddrawsurface7_setsurfacedesc,
1340 ddrawsurface7_setprivatedata,
1349 ddrawsurface7_getprivatedata,
1358 ddrawsurface7_freeprivatedata,
1364 ddrawsurface7_getuniquenessvalue,
1371 ddrawsurface7_changeuniquenessvalue,
1376 ddrawsurface7_setpriority,
1382 ddrawsurface7_getpriority,
1389 ddrawsurface7_setlod,
1395 ddrawsurface7_getlod,
1405 .AddAttachedSurface = ddrawsurface7_addattachedsurface,
1406 .AddOverlayDirtyRect = ddrawsurface7_addoverlaydirtyrect,
1408 .BltBatch = ddrawsurface7_bltbatch,
1409 .BltFast = ddrawsurface7_bltfast,
1410 .DeleteAttachedSurface = ddrawsurface7_deleteattachedsurface,
1411 .EnumAttachedSurfaces = ddrawsurface7_enumattachedsurfaces,
1412 .EnumOverlayZOrders = ddrawsurface7_enumoverlayzorders,
1413 .Flip = ddrawsurface7_flip,
1415 .GetBltStatus = ddrawsurface7_getbltstatus,
1416 .GetCaps = ddrawsurface7_getcaps,
1417 .GetClipper = ddrawsurface7_getclipper,
1418 .GetColorKey = ddrawsurface7_getcolorkey,
1419 .GetDC = ddrawsurface7_getdc,
1420 .GetFlipStatus = ddrawsurface7_getflipstatus,
1422 .GetPalette = ddrawsurface7_getpalette,
1423 .GetPixelFormat = ddrawsurface7_getpixelformat,
1425 .Initialize = ddrawsurface7_initialize,
1426 .IsLost = ddrawsurface7_islost,
1427 .Lock = ddrawsurface7_lock,
1428 .ReleaseDC = ddrawsurface7_releasedc,
1429 .Restore = ddrawsurface7_restore,
1430 .SetClipper = ddrawsurface7_setclipper,
1432 .SetOverlayPosition = ddrawsurface7_setoverlayposition,
1433 .SetPalette = ddrawsurface7_setpalette,
1435 .UpdateOverlay = ddrawsurface7_updateoverlay,
1436 .UpdateOverlayDisplay = ddrawsurface7_updateoverlaydisplay,
1437 .UpdateOverlayZOrder = ddrawsurface7_updateoverlayzorder,
1438 .GetDDInterface = ddrawsurface7_getddinterface,
1439 .PageLock = ddrawsurface7_pagelock,
1440 .PageUnlock = ddrawsurface7_pageunlock,
1441 .SetSurfaceDesc = ddrawsurface7_setsurfacedesc,
1442 .SetPrivateData = ddrawsurface7_setprivatedata,
1443 .GetPrivateData = ddrawsurface7_getprivatedata,
1444 .FreePrivateData = ddrawsurface7_freeprivatedata,
1445 .GetUniquenessValue = ddrawsurface7_getuniquenessvalue,
1446 .ChangeUniquenessValue = ddrawsurface7_changeuniquenessvalue,
1447 .SetPriority = ddrawsurface7_setpriority,
1448 .GetPriority = ddrawsurface7_getpriority,
1449 .SetLOD = ddrawsurface7_setlod,
1450 .GetLOD = ddrawsurface7_getlod,
1463 size_t pixel_size = 0;
1489 surf->
width = width;
1492 surf->
pitch = pitch;
1498 surf->
pixels = calloc(1, pixel_size);
static DTTR_Graphics_COM_Direct3D7_VT vtbl
DTTR_Graphics_COM_Direct3DDevice7 * self
DTTR_Graphics_COM_Direct3DDevice7 void *status DTTR_Graphics_COM_Direct3DDevice7 DWORD DWORD void DWORD DWORD f DTTR_Graphics_COM_Direct3DDevice7 DWORD void DWORD st
DTTR_Graphics_COM_Direct3DDevice7 void *status DTTR_Graphics_COM_Direct3DDevice7 DWORD DWORD void DWORD DWORD f DTTR_Graphics_COM_Direct3DDevice7 DWORD void DWORD DWORD DWORD f DTTR_Graphics_COM_Direct3DDevice7 void float * r
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD count
DTTR_Graphics_COM_Direct3DDevice7 void *status DTTR_Graphics_COM_Direct3DDevice7 DWORD DWORD void * d
const DTTR_BackendState * state
DTTR_Graphics_COM_Direct3DDevice7 DWORD block DTTR_Graphics_COM_Direct3DDevice7 DWORD block DTTR_Graphics_COM_Direct3DDevice7 void * dst
DTTR_Graphics_COM_Direct3DDevice7 void DWORD flags DWORD void DWORD flags
DTTR_Graphics_COM_Direct3DTexture2 * dttr_graphics_com_create_direct3d_texture2(DTTR_Graphics_COM_DirectDrawSurface7 *surface)
DTTR_Graphics_COM_DirectDraw7 *self DWORD DWORD DWORD bpp
DTTR_Graphics_COM_DirectDraw7 *self DWORD DWORD h
DTTR_Graphics_COM_DirectDraw7 *self DWORD w
DTTR_Graphics_COM_DirectDraw7 DWORD void * desc
static bool blit_rect_clip_to_surface(blit_rect *rect, uint32_t surface_w, uint32_t surface_h)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void DTTR_Graphics_COM_DirectDrawSurface7 *self DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags DTTR_Graphics_COM_DirectDrawSurface7 void * tag
DTTR_Graphics_COM_DirectDrawSurface7 *self DWORD void * colorKey
static void surface_upload_texture(DTTR_Graphics_COM_DirectDrawSurface7 *self)
Uploads dirty surface pixels to the staged texture cache.
DTTR_Graphics_COM_DirectDrawSurface7 DWORD static flags HRESULT ddrawsurface7_getoverlayposition(DTTR_Graphics_COM_DirectDrawSurface7 *self, LONG *x, LONG *y)
static DTTR_Texture surface_texture_create_or_retain(int width, int height, const void *pixels, uint64_t cache_key)
Creates or reuses a staged GPU texture handle for a CPU pixel buffer.
static HRESULT ddrawsurface7_getattachedsurface(DTTR_Graphics_COM_DirectDrawSurface7 *self, void *caps, void **surf)
static bool surface_bgra_upload_size(uint32_t width, uint32_t height, size_t *out_size)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD DWORD void * srcSurf
static bool surface_texture_cache_ensure_initialized()
DTTR_Graphics_COM_DirectDrawSurface7 void *static palette HRESULT ddrawsurface7_unlock(DTTR_Graphics_COM_DirectDrawSurface7 *self, void *rect)
static khash_t(dttr_surface_texture_cache)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD x
DTTR_Graphics_COM_DirectDrawSurface7 * dttr_graphics_com_create_directdrawsurface7(uint32_t width, uint32_t height, uint32_t bpp, uint32_t r_mask, uint32_t g_mask, uint32_t b_mask, uint32_t a_mask)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD DWORD void void * srcRect
DTTR_Graphics_COM_DirectDrawSurface7 void *static clipper HRESULT ddrawsurface7_setcolorkey(DTTR_Graphics_COM_DirectDrawSurface7 *self, DWORD flags, void *colorKey)
static HRESULT ddrawsurface7_getsurfacedesc(DTTR_Graphics_COM_DirectDrawSurface7 *self, void *desc)
static DTTR_Texture surface_texture_cache_lookup_locked(uint64_t key)
static uint64_t surface_hash_source_pixels(const DTTR_Graphics_COM_DirectDrawSurface7 *self, uint32_t upload_w, uint32_t upload_h)
static void surface_texture_cache_insert_locked(uint64_t key, DTTR_Texture tex)
void dttr_graphics_surface_texture_cache_reset()
static void surface_fill_pixelformat(const DTTR_Graphics_COM_DirectDrawSurface7 *self, DDPIXELFORMAT *pf)
static HRESULT blit_rect_from_optional(const RECT *rect, uint32_t default_w, uint32_t default_h, blit_rect *out)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD DWORD y
static void surface_fill_desc(const DTTR_Graphics_COM_DirectDrawSurface7 *self, DDSURFACEDESC2 *d)
Fills a caller-provided DDSURFACEDESC2 buffer from surface state.
static HRESULT ddrawsurface7_queryinterface(DTTR_Graphics_COM_DirectDrawSurface7 *self, void *riid, void **ppv)
static void surface_convert_rgb565_to_bgra8888(const uint16_t *restrict src, uint32_t *restrict dst, uint32_t w, uint32_t h, uint32_t src_pitch, bool has_colorkey, uint16_t colorkey)
Converts RGB565 pixels to BGRA8888 and applies black/colorkey transparency.
static void surface_queue_pending_upload_locked(DTTR_BackendState *state, int idx)
void void DWORD HANDLE event
DTTR_Graphics_COM_DirectDrawSurface7 void *static rect HRESULT ddrawsurface7_blt(DTTR_Graphics_COM_DirectDrawSurface7 *self, void *dstRect, void *srcSurf, void *srcRect, DWORD flags, void *bltFx)
static bool surface_texture_update_unique(DTTR_Texture tex, int width, int height, const void *pixels, uint64_t cache_key)
static void surface_convert_argb4444_to_bgra8888(const uint16_t *restrict src, uint32_t *restrict dst, uint32_t w, uint32_t h, uint32_t src_pitch)
Converts ARGB4444 surface pixels to BGRA8888 pixels.
static ULONG ddrawsurface7_release(DTTR_Graphics_COM_DirectDrawSurface7 *self)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void DTTR_Graphics_COM_DirectDrawSurface7 *self DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags DTTR_Graphics_COM_DirectDrawSurface7 void void * data
static void surface_texture_release(DTTR_Texture tex)
Releases one staged texture reference and destroys GPU resources at zero refs.
static void surface_texture_cache_remove_locked(uint64_t key, DTTR_Texture tex)
static uint32_t * surface_ensure_convert_buffer(DTTR_Graphics_COM_DirectDrawSurface7 *self, size_t size)
static uint32_t surface_texture_refcount(DTTR_Texture tex)
DTTR_Graphics_COM_DirectDrawSurface7 DWORD flags void NULL
DTTR_Graphics_COM_DirectDrawSurface7 DWORD DWORD void void DWORD flags DTTR_Graphics_COM_DirectDrawSurface7 void void *cb void * target
static uint64_t surface_texture_cache_key(const DTTR_Graphics_COM_DirectDrawSurface7 *self, uint32_t width, uint32_t height, uint64_t source_hash)
HRESULT dttr_graphics_com_validate_directdrawsurface7(uint32_t width, uint32_t height, uint32_t bpp, uint32_t *out_pitch, size_t *out_pixel_size)
static bool surface_texture_retain(DTTR_Texture tex)
static ULONG ddrawsurface7_addref(DTTR_Graphics_COM_DirectDrawSurface7 *self)
static void surface_present()
Ends and presents the current frame when a frame is active.
#define DTTR_LOG_ERROR(...)
void dttr_graphics_end_frame()
#define DTTR_SIZEOF_DDSURFACEDESC2
#define DTTR_COM_STUB_MEMSET(fn, size, buf_type,...)
#define DTTR_COM_STUB_SET(fn, out_type, val,...)
#define DTTR_COM_NOOP_HRESULT(fn,...)
#define DTTR_SIZEOF_DDSURFACEDESC
#define DTTR_SIZEOF_DDSCAPS2
#define DTTR_DDERR_GENERIC
DTTR_BackendState dttr_backend
#define DTTR_MAX_STAGED_TEXTURES
#define DTTR_INVALID_TEXTURE
DTTR_Graphics_COM_DirectDrawSurface7_VT * vtbl
DTTR_Graphics_COM_Direct3DTexture2 * texture