internal/graphicsdriver/playstation5: update DrawTriangles

A Go pointer in a C struct could cause some troubles.
This commit is contained in:
Hajime Hoshi 2024-08-10 18:18:09 +09:00
parent fbf40a4455
commit 332da38565
2 changed files with 23 additions and 46 deletions

View File

@ -118,26 +118,24 @@ func (g *Graphics) NewShader(program *shaderir.Program) (graphicsdriver.Shader,
} }
func (g *Graphics) DrawTriangles(dst graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shader graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error { func (g *Graphics) DrawTriangles(dst graphicsdriver.ImageID, srcs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shader graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error {
csrcs := make([]C.int, len(srcs)) cSrcs := make([]C.int, len(srcs))
for i, src := range srcs { for i, src := range srcs {
csrcs[i] = C.int(src) cSrcs[i] = C.int(src)
} }
defer runtime.KeepAlive(cSrcs)
cDstRegions := make([]C.ebitengine_DstRegion, len(dstRegions)) cDstRegions := make([]C.ebitengine_DstRegion, len(dstRegions))
defer runtime.KeepAlive(cDstRegions)
for i, r := range dstRegions { for i, r := range dstRegions {
cDstRegions[i] = C.ebitengine_DstRegion{ cDstRegions[i] = C.ebitengine_DstRegion{
Region: C.ebitengine_Rectangle{ MinX: C.int(r.Region.Min.X),
MinX: C.int(r.Region.Min.X), MinY: C.int(r.Region.Min.Y),
MinY: C.int(r.Region.Min.Y), MaxX: C.int(r.Region.Max.X),
MaxX: C.int(r.Region.Max.X), MaxY: C.int(r.Region.Max.Y),
MaxY: C.int(r.Region.Max.Y),
},
IndexCount: C.int(r.IndexCount), IndexCount: C.int(r.IndexCount),
} }
} }
cUniforms := make([]C.uint32_t, len(uniforms))
for i, u := range uniforms {
cUniforms[i] = C.uint32_t(u)
}
cBlend := C.ebitengine_Blend{ cBlend := C.ebitengine_Blend{
BlendFactorSourceRGB: C.uint8_t(blend.BlendFactorSourceRGB), BlendFactorSourceRGB: C.uint8_t(blend.BlendFactorSourceRGB),
BlendFactorSourceAlpha: C.uint8_t(blend.BlendFactorSourceAlpha), BlendFactorSourceAlpha: C.uint8_t(blend.BlendFactorSourceAlpha),
@ -147,23 +145,15 @@ func (g *Graphics) DrawTriangles(dst graphicsdriver.ImageID, srcs [graphics.Shad
BlendOperationAlpha: C.uint8_t(blend.BlendOperationAlpha), BlendOperationAlpha: C.uint8_t(blend.BlendOperationAlpha),
} }
args := C.ebitengine_DrawTrianglesArgs{ cUniforms := make([]C.uint32_t, len(uniforms))
Dst: C.int(dst), defer runtime.KeepAlive(cUniforms)
Srcs: &csrcs[0], for i, u := range uniforms {
SrcCount: C.int(len(csrcs)), cUniforms[i] = C.uint32_t(u)
Shader: C.int(shader),
DstRegions: &cDstRegions[0],
DstRegionCount: C.int(len(cDstRegions)),
IndexOffset: C.int(indexOffset),
Blend: cBlend,
Uniforms: &cUniforms[0],
UniformCount: C.int(len(cUniforms)),
FillRule: C.int(fillRule),
} }
if err := C.ebitengine_DrawTriangles(&args); !C.ebitengine_IsErrorNil(&err) {
if err := C.ebitengine_DrawTriangles(C.int(dst), &cSrcs[0], C.int(len(cSrcs)), C.int(shader), &cDstRegions[0], C.int(len(cDstRegions)), C.int(indexOffset), cBlend, &cUniforms[0], C.int(len(cUniforms)), C.int(fillRule)); !C.ebitengine_IsErrorNil(&err) {
return newPlaystation5Error("(*playstation5.Graphics).DrawTriangles", err) return newPlaystation5Error("(*playstation5.Graphics).DrawTriangles", err)
} }
runtime.KeepAlive(args)
return nil return nil
} }

View File

@ -34,15 +34,11 @@ static bool ebitengine_IsErrorNil(ebitengine_Error *err) {
return err->Message == NULL && err->Code == 0; return err->Message == NULL && err->Code == 0;
} }
typedef struct ebitengine_Rectangle { typedef struct ebitengine_DstRegion {
int MinX; int MinX;
int MinY; int MinY;
int MaxX; int MaxX;
int MaxY; int MaxY;
} ebitengine_Rectangle;
typedef struct ebitengine_DstRegion {
ebitengine_Rectangle Region;
int IndexCount; int IndexCount;
} ebitengine_DstRegion; } ebitengine_DstRegion;
@ -55,26 +51,17 @@ typedef struct ebitengine_Blend {
uint8_t BlendOperationAlpha; uint8_t BlendOperationAlpha;
} ebitengine_Blend; } ebitengine_Blend;
typedef struct ebitengine_DrawTrianglesArgs {
int Dst;
int *Srcs;
int SrcCount;
int Shader;
ebitengine_DstRegion *DstRegions;
int DstRegionCount;
int IndexOffset;
ebitengine_Blend Blend;
uint32_t *Uniforms;
int UniformCount;
int FillRule;
} ebitengine_DrawTrianglesArgs;
ebitengine_Error ebitengine_InitializeGraphics(void); ebitengine_Error ebitengine_InitializeGraphics(void);
ebitengine_Error ebitengine_NewImage(int *image, int width, int height); ebitengine_Error ebitengine_NewImage(int *image, int width, int height);
ebitengine_Error ebitengine_NewScreenFramebufferImage(int *image, int width, ebitengine_Error ebitengine_NewScreenFramebufferImage(int *image, int width,
int height); int height);
void ebitengine_DisposeImage(int id); void ebitengine_DisposeImage(int id);
ebitengine_Error ebitengine_DrawTriangles(ebitengine_DrawTrianglesArgs *args);
ebitengine_Error
ebitengine_DrawTriangles(int dst, int *srcs, int srcCount, int shader,
ebitengine_DstRegion *dstRegions, int dstRegionCount,
int indexOffset, ebitengine_Blend blend,
uint32_t *uniforms, int uniformCount, int fillRule);
ebitengine_Error ebitengine_NewShader(int *shader, const char *source); ebitengine_Error ebitengine_NewShader(int *shader, const char *source);
void ebitengine_DisposeShader(int id); void ebitengine_DisposeShader(int id);