gfx_surface: stills decode through the loader's request and set

A still's decode asks the loader for what the driver takes - 10-bit
where it samples it, the compressed payload as it lies in the file -
through image_texture_load_request and its buffer twin, rather than
an image_texture_load that only ever produced 8-bit. A set of files
decodes through image_texture_load_set, the parallel decode moved to
libretro-common as formats/image_texture_set.c: dispatch_apply on
Apple, threads of its own elsewhere, in order on one, and
image_texture_set_run for any other per-index work.

The loader sample gains the set lanes: files decoded together with
missing, empty and NULL paths left empty, and every index of a run
called exactly once.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-10-07 09:34:25 +02:00
1 parent 9773b6956b
commit bf1f5a4a70
14 files changed
+351 -178

No files matched your search

+2 -1
View File
@@ -516,7 +516,8 @@ ifneq ($(HAVE_STRL), 1)
endif
OBJ += $(LIBRETRO_COMM_DIR)/formats/image_texture.o \
$(LIBRETRO_COMM_DIR)/formats/image_texture_scale.o
$(LIBRETRO_COMM_DIR)/formats/image_texture_scale.o \
$(LIBRETRO_COMM_DIR)/formats/image_texture_set.o
ifeq ($(HAVE_IMAGEVIEWER), 1)
DEFINES += -DHAVE_IMAGEVIEWER
+24 -98
View File
@@ -17,13 +17,6 @@
#include <string.h>
#include <retro_miscellaneous.h>
#include <features/features_cpu.h>
#include <retro_atomic.h>
#ifdef HAVE_GCD
#include <dispatch/dispatch.h>
#elif defined(HAVE_THREADS)
#include <rthreads/rthreads.h>
#endif
#include "gfx_surface.h"
#include "gfx_instrument.h"
@@ -689,17 +682,33 @@ gfx_surface_t *gfx_surface_still(gfx_surface_t **slot,
return *slot;
}
/* What a still's decode is asked for: the order the caller named,
* 10-bit where the driver samples it, a compressed payload as it lies
* in the file */
static void gfx_surface_request(image_texture_request_t *req,
bool supports_rgba)
{
gfx_surface_requirements_t want;
req->rgba = supports_rgba;
req->want_10bit = gfx_surface_query_requirements(0, &want)
&& (want.formats & GFX_SURFACE_PIXFMT_2101010);
req->want_fp16 = false;
req->want_compressed = true;
}
bool gfx_surface_submit_buffer(gfx_surface_t *s,
enum image_type_enum type, const void *buf, size_t len,
bool supports_rgba)
{
image_texture_request_t req;
struct texture_image *img;
if (!s || !buf || !len)
return false;
if (!(img = (struct texture_image*)calloc(1, sizeof(*img))))
return false;
img->supports_rgba = supports_rgba;
if (!image_texture_load_buffer(img, type, (void*)buf, len))
gfx_surface_request(&req, supports_rgba);
if (!image_texture_load_buffer_request(img, type, buf, len, &req,
NULL, NULL))
{
free(img);
return false;
@@ -723,13 +732,14 @@ bool gfx_surface_take_image(gfx_surface_t *s, struct texture_image *img)
bool gfx_surface_submit_file(gfx_surface_t *s, const char *path,
bool supports_rgba)
{
image_texture_request_t req;
struct texture_image *img;
if (!s || !path || !*path)
return false;
if (!(img = (struct texture_image*)calloc(1, sizeof(*img))))
return false;
img->supports_rgba = supports_rgba;
if (!image_texture_load(img, path))
gfx_surface_request(&req, supports_rgba);
if (!image_texture_load_request(img, path, &req, NULL, NULL))
{
free(img);
return false;
@@ -737,85 +747,6 @@ bool gfx_surface_submit_file(gfx_surface_t *s, const char *path,
return gfx_surface_submit_image(s, img);
}
/* A set of files decoded together: the next index a worker takes,
* and the images they come back as */
typedef struct
{
const char *const *paths;
struct texture_image *imgs;
retro_atomic_int_t next;
unsigned n;
bool supports_rgba;
} gfx_surface_decode_set_t;
static void gfx_surface_decode_one(gfx_surface_decode_set_t *set,
unsigned i)
{
struct texture_image *img = &set->imgs[i];
img->supports_rgba = set->supports_rgba;
if (!set->paths[i] || !*set->paths[i]
|| !image_texture_load(img, set->paths[i]))
img->pixels = NULL;
}
#if !defined(HAVE_GCD) && defined(HAVE_THREADS)
static void gfx_surface_decode_set_run(void *data)
{
gfx_surface_decode_set_t *set = (gfx_surface_decode_set_t*)data;
for (;;)
{
unsigned i = (unsigned)retro_atomic_fetch_add_int(&set->next, 1);
if (i >= set->n)
return;
gfx_surface_decode_one(set, i);
}
}
#endif
/* The set, decoded: on Apple over the dispatch pool the task queue's
* decodes already run on, elsewhere on threads of its own, and on one
* thread where there is only one */
static void gfx_surface_decode_set(gfx_surface_decode_set_t *set)
{
#ifdef HAVE_GCD
if (set->n > 1)
{
gfx_surface_decode_set_t *at = set;
dispatch_apply(set->n,
dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
^(size_t i) { gfx_surface_decode_one(at, (unsigned)i); });
return;
}
#elif defined(HAVE_THREADS)
{
unsigned workers = cpu_features_get_core_amount();
if (workers > 8)
workers = 8;
if (workers > 1 && set->n > 1)
{
/* This thread decodes alongside the others; a worker that
* could not be made costs nothing but its share */
sthread_t *thread[8];
unsigned t, spawned = workers - 1;
if (spawned > set->n - 1)
spawned = set->n - 1;
for (t = 0; t < spawned; t++)
thread[t] = sthread_create(gfx_surface_decode_set_run, set);
gfx_surface_decode_set_run(set);
for (t = 0; t < spawned; t++)
if (thread[t])
sthread_join(thread[t]);
return;
}
}
#endif
{
unsigned i;
for (i = 0; i < set->n; i++)
gfx_surface_decode_one(set, i);
}
}
/* At most this many decodes in hand before they go up, whatever
* the set's size: a theme's icons are small, but there are many */
#define GFX_SURFACE_DECODE_BATCH 32
@@ -824,14 +755,13 @@ unsigned gfx_surface_submit_files(gfx_surface_t *const *slots,
const char *const *paths, unsigned n, bool supports_rgba)
{
struct texture_image imgs[GFX_SURFACE_DECODE_BATCH];
gfx_surface_decode_set_t set;
image_texture_request_t req;
unsigned done = 0, first;
if (!slots || !paths)
return 0;
set.imgs = imgs;
set.supports_rgba = supports_rgba;
gfx_surface_request(&req, supports_rgba);
for (first = 0; first < n; first += GFX_SURFACE_DECODE_BATCH)
{
@@ -839,11 +769,7 @@ unsigned gfx_surface_submit_files(gfx_surface_t *const *slots,
unsigned count = n - first;
if (count > GFX_SURFACE_DECODE_BATCH)
count = GFX_SURFACE_DECODE_BATCH;
memset(imgs, 0, count * sizeof(*imgs));
set.paths = paths + first;
set.n = count;
retro_atomic_int_init(&set.next, 0);
gfx_surface_decode_set(&set);
image_texture_load_set(paths + first, imgs, count, &req);
/* Up, in order, on this thread */
for (i = 0; i < count; i++)
+1
View File
@@ -451,6 +451,7 @@ VIDEO IMAGE
#include "../libretro-common/formats/image_texture.c"
#include "../libretro-common/formats/image_texture_scale.c"
#include "../libretro-common/formats/image_texture_set.c"
#ifdef HAVE_RTGA
#include "../libretro-common/formats/tga/rtga.c"
+79 -68
View File
@@ -438,26 +438,33 @@ void image_loader_free(image_loader_t *l)
free(l);
}
/* The loader run to completion over a whole buffer: the request from
* the caller's image, whose ->pix10 asks for 10-bit on the way in. */
static bool image_texture_load_internal(
enum image_type_enum type,
void *ptr,
size_t len,
struct texture_image *out_img,
static void image_texture_clear(struct texture_image *img)
{
img->supports_rgba = false;
img->pixels = NULL;
img->width = 0;
img->height = 0;
img->compressed = NULL;
img->pix10 = false;
img->fp16 = false;
}
bool image_texture_load_buffer_request(struct texture_image *out_img,
enum image_type_enum type, const void *ptr, size_t len,
const image_texture_request_t *req,
bool (*should_abort)(void *ud), void *abort_ud)
{
image_texture_request_t req;
image_loader_t *l;
enum image_loader_state st;
req.rgba = out_img->supports_rgba;
req.want_10bit = out_img->pix10;
req.want_fp16 = false;
req.want_compressed = true;
out_img->compressed = NULL;
if (!(l = image_loader_new(type, &req)))
if (!out_img)
return false;
out_img->compressed = NULL;
if (!ptr || !len || !(l = image_loader_new(type, req)))
{
image_texture_clear(out_img);
return false;
}
image_loader_set_abort(l, should_abort, abort_ud);
if (!image_loader_start(l, ptr, len, len))
{
@@ -471,9 +478,59 @@ static bool image_texture_load_internal(
return true;
}
image_loader_free(l);
image_texture_clear(out_img);
return false;
}
bool image_texture_load_request(struct texture_image *out_img,
const char *path, const image_texture_request_t *req,
bool (*should_abort)(void *ud), void *ud)
{
enum image_type_enum type = image_texture_get_type(path);
if (type != IMAGE_TYPE_NONE)
{
/* The synchronous read rides the data_transfer prefix spine
* like every other loader: filestream/VFS routing (overlays
* and driver assets from archive members or content://
* documents), 64-bit lengths, the hardware guard behind the
* read, and honest short-read detection. A zero budget fills
* to completion in one blocking call, which is this API's
* contract. */
struct data_transfer *dt = data_transfer_open_prefix(path, 0);
if (dt)
{
size_t file_len = 0;
const uint8_t *ptr = NULL;
data_transfer_iterate(dt, 0);
ptr = data_transfer_ptr(dt, &file_len);
if (data_transfer_complete(dt) && ptr && file_len
&& image_texture_load_buffer_request(out_img, type,
ptr, file_len, req, should_abort, ud))
{
data_transfer_free(dt);
return true;
}
data_transfer_free(dt);
}
}
if (out_img)
image_texture_clear(out_img);
return false;
}
/* The request the plain loads carry: the caller's image, whose
* ->pix10 asks for 10-bit on the way in */
static void image_texture_request_of(const struct texture_image *img,
image_texture_request_t *req)
{
req->rgba = img->supports_rgba;
req->want_10bit = img->pix10;
req->want_fp16 = false;
req->want_compressed = true;
}
bool image_texture_load(struct texture_image *out_img, const char *path)
{
return image_texture_load_ex(out_img, path, NULL, NULL);
@@ -648,63 +705,17 @@ bool image_texture_tile_gx(struct texture_image *img)
bool image_texture_load_buffer(struct texture_image *out_img,
enum image_type_enum type, void *buffer, size_t buffer_len)
{
if (type != IMAGE_TYPE_NONE)
{
if (image_texture_load_internal(
type, buffer, buffer_len, out_img, NULL, NULL))
return true;
}
out_img->supports_rgba = false;
out_img->pixels = NULL;
out_img->width = 0;
out_img->height = 0;
out_img->compressed = NULL;
return false;
image_texture_request_t req;
image_texture_request_of(out_img, &req);
return image_texture_load_buffer_request(out_img, type, buffer,
buffer_len, &req, NULL, NULL);
}
bool image_texture_load_ex(struct texture_image *out_img,
const char *path, bool (*should_abort)(void *ud), void *ud)
{
enum image_type_enum type = image_texture_get_type(path);
if (type != IMAGE_TYPE_NONE)
{
/* The synchronous read rides the data_transfer prefix spine
* like every other loader: filestream/VFS routing (overlays
* and driver assets from archive members or content://
* documents), 64-bit lengths, the hardware guard behind the
* read, and honest short-read detection. A zero budget fills
* to completion in one blocking call, which is this API's
* contract. */
struct data_transfer *dt = data_transfer_open_prefix(path, 0);
if (dt)
{
size_t file_len = 0;
const uint8_t *ptr = NULL;
data_transfer_iterate(dt, 0);
ptr = data_transfer_ptr(dt, &file_len);
if (data_transfer_complete(dt) && ptr && file_len
&& image_texture_load_internal(
type,
(void*)ptr, file_len, out_img, should_abort, ud))
{
data_transfer_free(dt);
return true;
}
data_transfer_free(dt);
}
}
out_img->supports_rgba = false;
out_img->pixels = NULL;
out_img->width = 0;
out_img->height = 0;
out_img->compressed = NULL;
out_img->pix10 = false;
out_img->fp16 = false;
return false;
image_texture_request_t req;
image_texture_request_of(out_img, &req);
return image_texture_load_request(out_img, path, &req,
should_abort, ud);
}
+138
View File
@@ -0,0 +1,138 @@
/* Copyright (C) 2010-2026 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (image_texture_set.c).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <string.h>
#include <boolean.h>
#include <formats/image.h>
#ifdef HAVE_GCD
#include <dispatch/dispatch.h>
#elif defined(HAVE_THREADS)
#include <retro_atomic.h>
#include <rthreads/rthreads.h>
#include <features/features_cpu.h>
#endif
#if !defined(HAVE_GCD) && defined(HAVE_THREADS)
/* The next index a worker takes */
typedef struct
{
void (*fn)(unsigned i, void *ud);
void *ud;
retro_atomic_int_t next;
unsigned n;
} image_texture_set_t;
static void image_texture_set_worker(void *data)
{
image_texture_set_t *set = (image_texture_set_t*)data;
for (;;)
{
unsigned i = (unsigned)retro_atomic_fetch_add_int(&set->next, 1);
if (i >= set->n)
return;
set->fn(i, set->ud);
}
}
#endif
void image_texture_set_run(unsigned n,
void (*fn)(unsigned i, void *ud), void *ud)
{
unsigned i;
if (!n || !fn)
return;
#ifdef HAVE_GCD
if (n > 1)
{
dispatch_apply(n,
dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0),
^(size_t at) { fn((unsigned)at, ud); });
return;
}
#elif defined(HAVE_THREADS)
{
unsigned workers = cpu_features_get_core_amount();
if (workers > 8)
workers = 8;
if (workers > 1 && n > 1)
{
/* This thread works alongside the others; a worker that
* could not be made costs nothing but its share */
image_texture_set_t set;
sthread_t *thread[8];
unsigned t, spawned = workers - 1;
set.fn = fn;
set.ud = ud;
set.n = n;
retro_atomic_int_init(&set.next, 0);
if (spawned > n - 1)
spawned = n - 1;
for (t = 0; t < spawned; t++)
thread[t] = sthread_create(image_texture_set_worker, &set);
image_texture_set_worker(&set);
for (t = 0; t < spawned; t++)
if (thread[t])
sthread_join(thread[t]);
return;
}
}
#endif
for (i = 0; i < n; i++)
fn(i, ud);
}
typedef struct
{
const char *const *paths;
struct texture_image *imgs;
const image_texture_request_t *req;
} image_texture_load_set_t;
static void image_texture_load_one(unsigned i, void *ud)
{
image_texture_load_set_t *set = (image_texture_load_set_t*)ud;
struct texture_image *img = &set->imgs[i];
if ( !set->paths[i] || !*set->paths[i]
|| !image_texture_load_request(img, set->paths[i], set->req,
NULL, NULL))
img->pixels = NULL;
}
unsigned image_texture_load_set(const char *const *paths,
struct texture_image *imgs, unsigned n,
const image_texture_request_t *req)
{
image_texture_load_set_t set;
unsigned i, done = 0;
if (!paths || !imgs || !n)
return 0;
memset(imgs, 0, (size_t)n * sizeof(*imgs));
set.paths = paths;
set.imgs = imgs;
set.req = req;
image_texture_set_run(n, image_texture_load_one, &set);
for (i = 0; i < n; i++)
if (imgs[i].pixels || imgs[i].compressed)
done++;
return done;
}
+28
View File
@@ -260,6 +260,34 @@ bool image_texture_scale(struct texture_image *img,
bool image_texture_load_buffer(struct texture_image *img,
enum image_type_enum type, void *s, size_t len);
/* The loader run to completion over a whole buffer or a file, with
* @req naming what the caller takes (NULL: the ordinary image). The
* abort hook is asked between steps; it may be NULL. False leaves
* @img empty. */
bool image_texture_load_buffer_request(struct texture_image *img,
enum image_type_enum type, const void *buf, size_t len,
const image_texture_request_t *req,
bool (*should_abort)(void *ud), void *ud);
bool image_texture_load_request(struct texture_image *img,
const char *path, const image_texture_request_t *req,
bool (*should_abort)(void *ud), void *ud);
/* Run @fn for every index below @n, across the cores at once where
* there are threads: on Apple over the dispatch pool, elsewhere on
* threads of its own with the caller working alongside, and in order
* on one thread where there is only one. Returns once every call has.
* In formats/image_texture_set.c. */
void image_texture_set_run(unsigned n,
void (*fn)(unsigned i, void *ud), void *ud);
/* Decode the @n files @paths name into @imgs together, each as
* image_texture_load_request does with @req; a path that is NULL,
* empty or unreadable leaves its image empty. Returns how many
* decoded. In formats/image_texture_set.c. */
unsigned image_texture_load_set(const char *const *paths,
struct texture_image *imgs, unsigned n,
const image_texture_request_t *req);
/* ->pix10 is an ask on the way in and an answer on the way out: set
* it before the call to have a decoder that can emit XRGB2101010 do
* so, and read it after to find out whether it did. Clear on entry
@@ -3,7 +3,8 @@ TARGET := image_loader_test
# The still loader (formats/image_texture.c) and the scale unit
# (formats/image_texture_scale.c), driven as a frontend task or a core
# would: whole buffer, timed steps against a fake clock, a prefix that
# grows, an abort, the APNG verdict, the request's answers.
# grows, an abort, the APNG verdict, the request's answers, and the
# set decode (formats/image_texture_set.c) across threads.
LIBRETRO_COMM_DIR := ../../..
SOURCES := image_loader_test.c \
@@ -18,6 +19,7 @@ SOURCES := image_loader_test.c \
$(LIBRETRO_COMM_DIR)/formats/data_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture_scale.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture_set.c \
$(LIBRETRO_COMM_DIR)/formats/image_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/png/rpng.c \
$(LIBRETRO_COMM_DIR)/formats/png/rpng_apng.c \
@@ -26,6 +28,7 @@ SOURCES := image_loader_test.c \
$(LIBRETRO_COMM_DIR)/gfx/scaler/scaler_filter.c \
$(LIBRETRO_COMM_DIR)/gfx/scaler/scaler_int.c \
$(LIBRETRO_COMM_DIR)/memmap/memmap.c \
$(LIBRETRO_COMM_DIR)/rthreads/rthreads.c \
$(LIBRETRO_COMM_DIR)/streams/file_stream.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream.c \
$(LIBRETRO_COMM_DIR)/streams/trans_stream_deflate.c \
@@ -37,7 +40,7 @@ SOURCES := image_loader_test.c \
OBJS := $(SOURCES:.c=.o)
CFLAGS += -Wall -pedantic -std=gnu99 -g -O0 -DHAVE_RPNG \
CFLAGS += -Wall -pedantic -std=gnu99 -g -O0 -DHAVE_RPNG -DHAVE_THREADS \
-I$(LIBRETRO_COMM_DIR)/include
ifneq ($(SANITIZER),)
@@ -51,7 +54,7 @@ all: $(TARGET)
$(CC) -c -o $@ $< $(CFLAGS)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) -lm
$(CC) -o $@ $^ $(LDFLAGS) -lm -lpthread
clean:
rm -f $(TARGET) $(TARGET).exe $(OBJS)
@@ -12,6 +12,8 @@
* 6 the request's channel order is answered and honoured
* 7 image_texture_scale: the cap, the whole-factor upscale, and
* a half-float image left alone
* 8 image_texture_load_set: a set of files decoded together, an
* unreadable one left empty, every index run exactly once
*
* The PNG is built here - RGB, every row filter 0, the zlib stream
* stored and split across many small IDATs so the transfer has many
@@ -187,6 +189,11 @@ static int64_t fake_now(void)
return fake_now_v;
}
static void set_hit(unsigned i, void *ud)
{
((unsigned*)ud)[i]++;
}
static int aborts;
static bool abort_now(void *ud)
{
@@ -339,6 +346,52 @@ int main(void)
free(s.pixels);
}
/* 8: a set */
{
static const char *names[5] = {
"image_loader_set_0.png", "image_loader_set_1.png",
"image_loader_none.png", "", "image_loader_set_2.png" };
const char *paths[6];
struct texture_image imgs[6];
unsigned i, ok = 1, got;
for (i = 0; i < 5; i++)
{
FILE *f;
paths[i] = names[i];
if (i == 2 || i == 3)
continue;
if ((f = fopen(names[i], "wb")))
{
fwrite(png, 1, len, f);
fclose(f);
}
}
paths[5] = NULL;
req.rgba = false;
got = image_texture_load_set(paths, imgs, 6, &req);
for (i = 0; i < 6; i++)
{
bool want = (i == 0 || i == 1 || i == 4);
if (want ? !pixels_match(&imgs[i], false) : (imgs[i].pixels != NULL))
ok = 0;
image_texture_free(&imgs[i]);
}
CHECK(got == 3 && ok, "a set decodes its files; missing, empty and NULL paths stay empty");
for (i = 0; i < 5; i++)
if (i != 2 && i != 3)
remove(names[i]);
}
{
static unsigned hits[64];
unsigned i, ok = 1;
memset(hits, 0, sizeof(hits));
image_texture_set_run(64, set_hit, hits);
for (i = 0; i < 64; i++)
if (hits[i] != 1)
ok = 0;
CHECK(ok, "image_texture_set_run calls every index exactly once");
}
image_texture_free(&ref);
free(png);
free(apng);
+5 -3
View File
@@ -1,13 +1,15 @@
# gfx_surface stills against a stub driver, a simulated threaded
# wrapper, a held task queue and a stub image decoder: a still owns
# its texture across uploads, decodes and a free in flight, and a set
# of files is decoded across threads and goes up in order.
# wrapper, a held task queue and a stub image decoder under the real
# set decode (image_texture_set.c): a still owns its texture across
# uploads, decodes and a free in flight, and a set of files is decoded
# across threads and goes up in order.
RA := ../../..
CC ?= gcc
CFLAGS += -Wall -Wextra -g -O1 -std=gnu99 -I$(RA) -I$(RA)/libretro-common/include \
-I$(RA)/deps -DHAVE_THREADS -DRARCH_INTERNAL $(EXTRA_CFLAGS)
SRC := gfx_surface_still_test.c \
$(RA)/gfx/gfx_surface.c $(RA)/gfx/gfx_instrument.c \
$(RA)/libretro-common/formats/image_texture_set.c \
$(RA)/libretro-common/compat/compat_strl.c \
$(RA)/libretro-common/rthreads/rthreads.c \
$(RA)/libretro-common/features/features_cpu.c \
@@ -131,9 +131,12 @@ static uintptr_t st_decode_thread[ST_DECODE_THREADS];
static unsigned st_decode_threads;
static slock_t *st_decode_lock;
bool image_texture_load(struct texture_image *img, const char *path)
bool image_texture_load_request(struct texture_image *img,
const char *path, const image_texture_request_t *req,
bool (*should_abort)(void *ud), void *ud)
{
unsigned w = (unsigned)atoi(path);
(void)req; (void)should_abort; (void)ud;
if (!w)
return false;
retro_sleep(2);
@@ -153,10 +156,13 @@ bool image_texture_load(struct texture_image *img, const char *path)
return true;
}
bool image_texture_load_buffer(struct texture_image *img,
enum image_type_enum type, void *s, size_t len)
bool image_texture_load_buffer_request(struct texture_image *img,
enum image_type_enum type, const void *s, size_t len,
const image_texture_request_t *req,
bool (*should_abort)(void *ud), void *ud)
{
(void)img; (void)type; (void)s; (void)len;
(void)img; (void)type; (void)s; (void)len; (void)req;
(void)should_abort; (void)ud;
return false;
}
+1
View File
@@ -36,6 +36,7 @@ SOURCES := gfx_thumbnail_anim_test.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/formats/data_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture_set.c \
$(LIBRETRO_COMM_DIR)/formats/image_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/vp8/rvp8.c \
$(LIBRETRO_COMM_DIR)/formats/webp/rwebp.c \
@@ -52,6 +52,7 @@ SOURCES := gfx_thumbnail_preview_test.c \
$(LIBRETRO_COMM_DIR)/formats/audio_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/data_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture_set.c \
$(LIBRETRO_COMM_DIR)/formats/image_transfer.c \
$(LIBRETRO_COMM_DIR)/formats/image/image_hdr_blit.c \
$(LIBRETRO_COMM_DIR)/formats/image/image_blit_bands.c \
+1
View File
@@ -18,6 +18,7 @@ SOURCES := \
$(LIBRETRO_COMM_DIR)/file/file_path.c \
$(LIBRETRO_COMM_DIR)/file/file_path_io.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture_set.c \
$(LIBRETRO_COMM_DIR)/formats/png/rpng.c \
$(LIBRETRO_COMM_DIR)/formats/png/rpng_apng.c \
$(LIBRETRO_COMM_DIR)/lists/string_list.c \
+2 -1
View File
@@ -12,7 +12,8 @@ SOURCES := \
$(REPO_ROOT)/input/input_overlay_textures.c \
$(REPO_ROOT)/input/input_overlay_alpha.c \
$(REPO_ROOT)/gfx/gfx_surface.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture.c
$(LIBRETRO_COMM_DIR)/formats/image_texture.c \
$(LIBRETRO_COMM_DIR)/formats/image_texture_set.c
OBJS := $(SOURCES:.c=.o)