4#include <TargetConditionals.h>
5#import <CoreFoundation/CoreFoundation.h>
8#if defined(__APPLE__) && (TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1)
10#import <MetalKit/MetalKit.h>
28#if defined(__APPLE__) && (TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1)
30 LOG_WARN(
"MetalRenderer",
"Metal view not attached");
34 id<MTLDevice> device = view.device;
36 device = MTLCreateSystemDefaultDevice();
40 LOG_WARN(
"MetalRenderer",
"Failed to create Metal device");
44 id<MTLCommandQueue> queue = [device newCommandQueue];
62#if defined(__APPLE__) && (TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1)
68 id<MTLDevice> device = view.device;
70 device = MTLCreateSystemDefaultDevice();
77 MTLTextureDescriptor* descriptor =
78 [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
82 descriptor.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
83 descriptor.storageMode = MTLStorageModeShared;
85 id<MTLTexture> texture = [device newTextureWithDescriptor:descriptor];
86 return texture ? (__bridge_retained
void*)texture :
nullptr;
103#if defined(__APPLE__) && (TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1)
108 SDL_Surface* surface = bitmap.
surface();
109 if (!surface || !surface->pixels || surface->w <= 0 || surface->h <= 0) {
113 auto converted_surface =
114 std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(
116 if (!converted_surface || !converted_surface->pixels) {
120 id<MTLTexture> metal_texture = (__bridge id<MTLTexture>)texture;
123 {
static_cast<NSUInteger
>(converted_surface->w),
124 static_cast<NSUInteger
>(converted_surface->h),
126 [metal_texture replaceRegion:region
128 withBytes:converted_surface->pixels
129 bytesPerRow:converted_surface->pitch];
143#if defined(__APPLE__) && (TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1)
151 void** pixels,
int* pitch) {
170 const SDL_Rect* dstrect) {
171#if defined(__APPLE__) && (TARGET_OS_IPHONE == 1 || TARGET_IPHONE_SIMULATOR == 1)
176 id<MTLTexture> source = (__bridge id<MTLTexture>)texture;
179 int src_x = srcrect ? srcrect->x : 0;
180 int src_y = srcrect ? srcrect->y : 0;
181 int src_w = srcrect ? srcrect->w :
static_cast<int>(source.width);
182 int src_h = srcrect ? srcrect->h :
static_cast<int>(source.height);
184 int dst_x = dstrect ? dstrect->x : 0;
185 int dst_y = dstrect ? dstrect->y : 0;
187 src_w = std::min(src_w,
static_cast<int>(source.width) - src_x);
188 src_h = std::min(src_h,
static_cast<int>(source.height) - src_y);
190 if (src_w <= 0 || src_h <= 0) {
194 MTLOrigin src_origin = {
static_cast<NSUInteger
>(src_x),
195 static_cast<NSUInteger
>(src_y),
197 MTLSize src_size = {
static_cast<NSUInteger
>(src_w),
198 static_cast<NSUInteger
>(src_h),
200 MTLOrigin dst_origin = {
static_cast<NSUInteger
>(dst_x),
201 static_cast<NSUInteger
>(dst_y),
204 id<MTLCommandQueue> queue = (__bridge id<MTLCommandQueue>)
command_queue_;
205 id<MTLCommandBuffer> command_buffer = [queue commandBuffer];
206 id<MTLBlitCommandEncoder> blit = [command_buffer blitCommandEncoder];
207 [blit copyFromTexture:source
210 sourceOrigin:src_origin
215 destinationOrigin:dst_origin];
217 [command_buffer commit];
218 [command_buffer waitUntilCompleted];
Represents a bitmap image optimized for SNES ROM hacking.
SDL_Surface * surface() const
#define LOG_WARN(category, format,...)
void * TextureHandle
An abstract handle representing a texture.
SDL2/SDL3 compatibility layer.