Add "device_affinity" keyword argument to Bitmap.new binding

0 (default) prefers accelerated GPU.
1 prefers CPU (initializes as a Mega Surface).

There are at least 3 situations where CPU is likely to be faster:

1. Raster effects implemented in Ruby (e.g. via set_pixel).
2. Operations on background threads.
3. Platforms without accelerated OpenGL (e.g. LLVMPipe).
This commit is contained in:
Splendide Imaginarius 2024-10-06 11:03:19 +00:00
parent 711f9a4553
commit faf17e64f2
3 changed files with 36 additions and 14 deletions

View file

@ -66,16 +66,38 @@ void bitmapInitProps(Bitmap *b, VALUE self) {
RB_METHOD_GUARD(bitmapInitialize) {
Bitmap *b = 0;
if (argc == 1) {
char *filename;
rb_get_args(argc, argv, "z", &filename RB_ARG_END);
GFX_GUARD_EXC(b = new Bitmap(filename);)
} else {
int width, height;
rb_get_args(argc, argv, "ii", &width, &height RB_ARG_END);
VALUE arg1;
VALUE arg2;
VALUE kwargs;
rb_scan_args(argc, argv, "11:", &arg1, &arg2, &kwargs);
ID table[1];
table[0] = rb_intern("device_affinity");
VALUE deviceAffinity;
rb_get_kwargs(kwargs, table, 0, 1, &deviceAffinity);
if (RB_TYPE_P(arg1, RUBY_T_STRING)) {
// filename constructor, arg1 is filename
SafeStringValue(arg1);
int affinity = 0;
if (deviceAffinity != Qundef && deviceAffinity != Qnil) {
affinity = NUM2INT(deviceAffinity);
}
bool forceMega = false;
if (affinity == 1) {
forceMega = true;
}
GFX_GUARD_EXC(b = new Bitmap(RSTRING_PTR(arg1), forceMega);)
}
else {
// width,height constructor
int width = NUM2INT(arg1);
int height = NUM2INT(arg2);
GFX_GUARD_EXC(b = new Bitmap(width, height);)
}

View file

@ -488,7 +488,7 @@ struct BitmapOpenHandler : FileSystem::OpenHandler
}
};
Bitmap::Bitmap(const char *filename)
Bitmap::Bitmap(const char *filename, bool forceMega)
{
std::string hiresPrefix = "Hires/";
std::string filenameStd = filename;
@ -498,7 +498,7 @@ Bitmap::Bitmap(const char *filename)
// Look for a high-res version of the file.
std::string hiresFilename = hiresPrefix + filenameStd;
try {
hiresBitmap = new Bitmap(hiresFilename.c_str());
hiresBitmap = new Bitmap(hiresFilename.c_str(), forceMega);
hiresBitmap->setLores(this);
}
catch (const Exception &e)
@ -631,7 +631,7 @@ Bitmap::Bitmap(const char *filename)
SDL_Surface *imgSurf = handler.surface;
initFromSurface(imgSurf, hiresBitmap, false);
initFromSurface(imgSurf, hiresBitmap, forceMega);
}
Bitmap::Bitmap(int width, int height, bool isHires)

View file

@ -38,7 +38,7 @@ struct BitmapPrivate;
class Bitmap : public Disposable
{
public:
Bitmap(const char *filename);
Bitmap(const char *filename, bool forceMega = false);
Bitmap(int width, int height, bool isHires = false);
Bitmap(void *pixeldata, int width, int height);
Bitmap(TEXFBO &other);