mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-11 07:02:31 +00:00
wg_engine: introduced scene opacity
[issues 1479: opacity](#1479) Supported opacity value for scene Usage example: //Create a Scene auto scene = tvg::Scene::gen(); scene->opacity(100); //Prepare Circle auto shape1 = tvg::Shape::gen(); shape1->appendCircle(400, 400, 250, 250); shape1->fill(255, 255, 0); shape1->opacity(100); scene->push(std::move(shape1)); //Round rectangle auto shape2 = tvg::Shape::gen(); shape2->appendRect(450, 100, 200, 200, 50, 50); shape2->fill(0, 255, 0); shape2->strokeWidth(10); shape2->strokeFill(255, 255, 255); scene->push(std::move(shape2)); canvas->push(std::move(scene));
This commit is contained in:
parent
780f30bfcc
commit
96e0794a67
11 changed files with 331 additions and 157 deletions
|
@ -29,6 +29,7 @@ WGPUBindGroupLayout WgBindGroupSolidColor::layout = nullptr;
|
||||||
WGPUBindGroupLayout WgBindGroupLinearGradient::layout = nullptr;
|
WGPUBindGroupLayout WgBindGroupLinearGradient::layout = nullptr;
|
||||||
WGPUBindGroupLayout WgBindGroupRadialGradient::layout = nullptr;
|
WGPUBindGroupLayout WgBindGroupRadialGradient::layout = nullptr;
|
||||||
WGPUBindGroupLayout WgBindGroupPicture::layout = nullptr;
|
WGPUBindGroupLayout WgBindGroupPicture::layout = nullptr;
|
||||||
|
WGPUBindGroupLayout WgBindGroupOpacity::layout = nullptr;
|
||||||
WGPUBindGroupLayout WgBindGroupBlit::layout = nullptr;
|
WGPUBindGroupLayout WgBindGroupBlit::layout = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
@ -258,6 +259,50 @@ void WgBindGroupPicture::release()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WGPUBindGroupLayout WgBindGroupOpacity::getLayout(WGPUDevice device)
|
||||||
|
{
|
||||||
|
if (layout) return layout;
|
||||||
|
const WGPUBindGroupLayoutEntry bindGroupLayoutEntries[] {
|
||||||
|
makeBindGroupLayoutEntryBuffer(0)
|
||||||
|
};
|
||||||
|
layout = createBindGroupLayout(device, bindGroupLayoutEntries, 1);
|
||||||
|
assert(layout);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgBindGroupOpacity::releaseLayout()
|
||||||
|
{
|
||||||
|
releaseBindGroupLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgBindGroupOpacity::initialize(WGPUDevice device, WGPUQueue queue, uint32_t uOpacity)
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
float opacity = uOpacity / 255.0f;
|
||||||
|
uBufferOpacity = createBuffer(device, queue, &opacity, sizeof(float));
|
||||||
|
const WGPUBindGroupEntry bindGroupEntries[] {
|
||||||
|
makeBindGroupEntryBuffer(0, uBufferOpacity)
|
||||||
|
};
|
||||||
|
mBindGroup = createBindGroup(device, getLayout(device), bindGroupEntries, 1);
|
||||||
|
assert(mBindGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgBindGroupOpacity::update(WGPUDevice device, WGPUQueue queue, uint32_t uOpacity) {
|
||||||
|
float opacity = uOpacity / 255.0f;
|
||||||
|
wgpuQueueWriteBuffer(queue, uBufferOpacity, 0, &opacity, sizeof(float));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgBindGroupOpacity::release()
|
||||||
|
{
|
||||||
|
releaseBuffer(uBufferOpacity);
|
||||||
|
releaseBindGroup(mBindGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUBindGroupLayout WgBindGroupBlit::getLayout(WGPUDevice device)
|
WGPUBindGroupLayout WgBindGroupBlit::getLayout(WGPUDevice device)
|
||||||
{
|
{
|
||||||
if (layout) return layout;
|
if (layout) return layout;
|
||||||
|
@ -292,4 +337,46 @@ void WgBindGroupBlit::initialize(WGPUDevice device, WGPUQueue queue, WGPUSampler
|
||||||
void WgBindGroupBlit::release()
|
void WgBindGroupBlit::release()
|
||||||
{
|
{
|
||||||
releaseBindGroup(mBindGroup);
|
releaseBindGroup(mBindGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// bind groups pools
|
||||||
|
//************************************************************************
|
||||||
|
|
||||||
|
WgBindGroupOpacity* WgBindGroupOpacityPool::allocate(WgContext& context, uint32_t opacity)
|
||||||
|
{
|
||||||
|
WgBindGroupOpacity* bindGroup{};
|
||||||
|
if (mPool.count == 0) {
|
||||||
|
bindGroup = new WgBindGroupOpacity;
|
||||||
|
bindGroup->initialize(context.device, context.queue, opacity);
|
||||||
|
mUsed.push(bindGroup);
|
||||||
|
mList.push(bindGroup);
|
||||||
|
} else {
|
||||||
|
bindGroup = mPool.last();
|
||||||
|
bindGroup->update(context.device, context.queue, opacity);
|
||||||
|
mUsed.push(bindGroup);
|
||||||
|
mPool.pop();
|
||||||
|
}
|
||||||
|
return bindGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgBindGroupOpacityPool::reset()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < mUsed.count; i++)
|
||||||
|
mPool.push(mUsed[i]);
|
||||||
|
mUsed.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgBindGroupOpacityPool::release()
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < mList.count; i++) {
|
||||||
|
mList[i]->release();
|
||||||
|
delete mList[i];
|
||||||
|
}
|
||||||
|
mList.clear();
|
||||||
|
mUsed.clear();
|
||||||
|
mPool.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ struct WgBindGroupSolidColor : public WgBindGroup
|
||||||
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
||||||
static void releaseLayout();
|
static void releaseLayout();
|
||||||
|
|
||||||
WGPUBuffer uBufferSolidColor;
|
WGPUBuffer uBufferSolidColor{};
|
||||||
void initialize(WGPUDevice device, WGPUQueue queue,
|
void initialize(WGPUDevice device, WGPUQueue queue,
|
||||||
WgShaderTypeSolidColor &uSolidColor);
|
WgShaderTypeSolidColor &uSolidColor);
|
||||||
void release();
|
void release();
|
||||||
|
@ -75,7 +75,7 @@ struct WgBindGroupLinearGradient : public WgBindGroup
|
||||||
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
||||||
static void releaseLayout();
|
static void releaseLayout();
|
||||||
|
|
||||||
WGPUBuffer uBufferLinearGradient;
|
WGPUBuffer uBufferLinearGradient{};
|
||||||
void initialize(WGPUDevice device, WGPUQueue queue,
|
void initialize(WGPUDevice device, WGPUQueue queue,
|
||||||
WgShaderTypeLinearGradient &uLinearGradient);
|
WgShaderTypeLinearGradient &uLinearGradient);
|
||||||
void release();
|
void release();
|
||||||
|
@ -88,7 +88,7 @@ struct WgBindGroupRadialGradient : public WgBindGroup
|
||||||
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
||||||
static void releaseLayout();
|
static void releaseLayout();
|
||||||
|
|
||||||
WGPUBuffer uBufferRadialGradient;
|
WGPUBuffer uBufferRadialGradient{};
|
||||||
void initialize(WGPUDevice device, WGPUQueue queue,
|
void initialize(WGPUDevice device, WGPUQueue queue,
|
||||||
WgShaderTypeRadialGradient &uRadialGradient);
|
WgShaderTypeRadialGradient &uRadialGradient);
|
||||||
void release();
|
void release();
|
||||||
|
@ -107,6 +107,19 @@ struct WgBindGroupPicture : public WgBindGroup
|
||||||
void release();
|
void release();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @group(1 or 2)
|
||||||
|
struct WgBindGroupOpacity : public WgBindGroup
|
||||||
|
{
|
||||||
|
static WGPUBindGroupLayout layout;
|
||||||
|
static WGPUBindGroupLayout getLayout(WGPUDevice device);
|
||||||
|
static void releaseLayout();
|
||||||
|
|
||||||
|
WGPUBuffer uBufferOpacity{};
|
||||||
|
void initialize(WGPUDevice device, WGPUQueue queue, uint32_t uOpacity);
|
||||||
|
void update(WGPUDevice device, WGPUQueue queue, uint32_t uOpacity);
|
||||||
|
void release();
|
||||||
|
};
|
||||||
|
|
||||||
// @group(0 or 1)
|
// @group(0 or 1)
|
||||||
struct WgBindGroupBlit : public WgBindGroup
|
struct WgBindGroupBlit : public WgBindGroup
|
||||||
{
|
{
|
||||||
|
@ -120,4 +133,20 @@ struct WgBindGroupBlit : public WgBindGroup
|
||||||
void release();
|
void release();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//************************************************************************
|
||||||
|
// bind group pools
|
||||||
|
//************************************************************************
|
||||||
|
|
||||||
|
class WgBindGroupOpacityPool
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Array<WgBindGroupOpacity*> mList;
|
||||||
|
Array<WgBindGroupOpacity*> mPool;
|
||||||
|
Array<WgBindGroupOpacity*> mUsed;
|
||||||
|
public:
|
||||||
|
WgBindGroupOpacity* allocate(WgContext& context, uint32_t opacity);
|
||||||
|
void reset();
|
||||||
|
void release();
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _TVG_WG_BIND_GROUPS_H_
|
#endif // _TVG_WG_BIND_GROUPS_H_
|
||||||
|
|
|
@ -272,7 +272,57 @@ void WgBindGroup::releaseBindGroupLayout(WGPUBindGroupLayout& bindGroupLayout)
|
||||||
// pipeline
|
// pipeline
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
|
||||||
void WgPipeline::allocate(WGPUDevice device,
|
void WgPipeline::release()
|
||||||
|
{
|
||||||
|
destroyShaderModule(mShaderModule);
|
||||||
|
destroyPipelineLayout(mPipelineLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WGPUPipelineLayout WgPipeline::createPipelineLayout(WGPUDevice device, const WGPUBindGroupLayout* bindGroupLayouts, uint32_t count)
|
||||||
|
{
|
||||||
|
WGPUPipelineLayoutDescriptor pipelineLayoutDesc{};
|
||||||
|
pipelineLayoutDesc.nextInChain = nullptr;
|
||||||
|
pipelineLayoutDesc.label = "The Pipeline layout";
|
||||||
|
pipelineLayoutDesc.bindGroupLayoutCount = count;
|
||||||
|
pipelineLayoutDesc.bindGroupLayouts = bindGroupLayouts;
|
||||||
|
return wgpuDeviceCreatePipelineLayout(device, &pipelineLayoutDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WGPUShaderModule WgPipeline::createShaderModule(WGPUDevice device, const char* code, const char* label)
|
||||||
|
{
|
||||||
|
WGPUShaderModuleWGSLDescriptor shaderModuleWGSLDesc{};
|
||||||
|
shaderModuleWGSLDesc.chain.next = nullptr;
|
||||||
|
shaderModuleWGSLDesc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
||||||
|
shaderModuleWGSLDesc.code = code;
|
||||||
|
WGPUShaderModuleDescriptor shaderModuleDesc{};
|
||||||
|
shaderModuleDesc.nextInChain = &shaderModuleWGSLDesc.chain;
|
||||||
|
shaderModuleDesc.label = label;
|
||||||
|
shaderModuleDesc.hintCount = 0;
|
||||||
|
shaderModuleDesc.hints = nullptr;
|
||||||
|
return wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgPipeline::destroyPipelineLayout(WGPUPipelineLayout& pipelineLayout)
|
||||||
|
{
|
||||||
|
if (pipelineLayout) wgpuPipelineLayoutRelease(pipelineLayout);
|
||||||
|
pipelineLayout = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WgPipeline::destroyShaderModule(WGPUShaderModule& shaderModule)
|
||||||
|
{
|
||||||
|
if (shaderModule) wgpuShaderModuleRelease(shaderModule);
|
||||||
|
shaderModule = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// render pipeline
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
void WgRenderPipeline::allocate(WGPUDevice device,
|
||||||
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
||||||
WGPUBindGroupLayout bindGroupLayouts[], uint32_t bindGroupsCount,
|
WGPUBindGroupLayout bindGroupLayouts[], uint32_t bindGroupsCount,
|
||||||
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
||||||
|
@ -292,21 +342,20 @@ void WgPipeline::allocate(WGPUDevice device,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgPipeline::release()
|
void WgRenderPipeline::release()
|
||||||
{
|
{
|
||||||
destroyRenderPipeline(mRenderPipeline);
|
destroyRenderPipeline(mRenderPipeline);
|
||||||
destroyShaderModule(mShaderModule);
|
WgPipeline::release();
|
||||||
destroyPipelineLayout(mPipelineLayout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgPipeline::set(WGPURenderPassEncoder renderPassEncoder)
|
void WgRenderPipeline::set(WGPURenderPassEncoder renderPassEncoder)
|
||||||
{
|
{
|
||||||
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, mRenderPipeline);
|
wgpuRenderPassEncoderSetPipeline(renderPassEncoder, mRenderPipeline);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
WGPUBlendState WgPipeline::makeBlendState()
|
WGPUBlendState WgRenderPipeline::makeBlendState()
|
||||||
{
|
{
|
||||||
WGPUBlendState blendState{};
|
WGPUBlendState blendState{};
|
||||||
blendState.color.operation = WGPUBlendOperation_Add;
|
blendState.color.operation = WGPUBlendOperation_Add;
|
||||||
|
@ -314,12 +363,12 @@ WGPUBlendState WgPipeline::makeBlendState()
|
||||||
blendState.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
blendState.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
||||||
blendState.alpha.operation = WGPUBlendOperation_Add;
|
blendState.alpha.operation = WGPUBlendOperation_Add;
|
||||||
blendState.alpha.srcFactor = WGPUBlendFactor_One;
|
blendState.alpha.srcFactor = WGPUBlendFactor_One;
|
||||||
blendState.alpha.dstFactor = WGPUBlendFactor_Zero;
|
blendState.alpha.dstFactor = WGPUBlendFactor_One;
|
||||||
return blendState;
|
return blendState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUColorTargetState WgPipeline::makeColorTargetState(const WGPUBlendState* blendState)
|
WGPUColorTargetState WgRenderPipeline::makeColorTargetState(const WGPUBlendState* blendState)
|
||||||
{
|
{
|
||||||
WGPUColorTargetState colorTargetState{};
|
WGPUColorTargetState colorTargetState{};
|
||||||
colorTargetState.nextInChain = nullptr;
|
colorTargetState.nextInChain = nullptr;
|
||||||
|
@ -330,7 +379,7 @@ WGPUColorTargetState WgPipeline::makeColorTargetState(const WGPUBlendState* blen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUVertexBufferLayout WgPipeline::makeVertexBufferLayout(const WGPUVertexAttribute* vertexAttributes, uint32_t count, uint64_t stride)
|
WGPUVertexBufferLayout WgRenderPipeline::makeVertexBufferLayout(const WGPUVertexAttribute* vertexAttributes, uint32_t count, uint64_t stride)
|
||||||
{
|
{
|
||||||
WGPUVertexBufferLayout vertexBufferLayoutPos{};
|
WGPUVertexBufferLayout vertexBufferLayoutPos{};
|
||||||
vertexBufferLayoutPos.arrayStride = stride;
|
vertexBufferLayoutPos.arrayStride = stride;
|
||||||
|
@ -341,7 +390,7 @@ WGPUVertexBufferLayout WgPipeline::makeVertexBufferLayout(const WGPUVertexAttrib
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUVertexState WgPipeline::makeVertexState(WGPUShaderModule shaderModule, const WGPUVertexBufferLayout* buffers, uint32_t count)
|
WGPUVertexState WgRenderPipeline::makeVertexState(WGPUShaderModule shaderModule, const WGPUVertexBufferLayout* buffers, uint32_t count)
|
||||||
{
|
{
|
||||||
WGPUVertexState vertexState{};
|
WGPUVertexState vertexState{};
|
||||||
vertexState.nextInChain = nullptr;
|
vertexState.nextInChain = nullptr;
|
||||||
|
@ -355,7 +404,7 @@ WGPUVertexState WgPipeline::makeVertexState(WGPUShaderModule shaderModule, const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUPrimitiveState WgPipeline::makePrimitiveState()
|
WGPUPrimitiveState WgRenderPipeline::makePrimitiveState()
|
||||||
{
|
{
|
||||||
WGPUPrimitiveState primitiveState{};
|
WGPUPrimitiveState primitiveState{};
|
||||||
primitiveState.nextInChain = nullptr;
|
primitiveState.nextInChain = nullptr;
|
||||||
|
@ -366,7 +415,7 @@ WGPUPrimitiveState WgPipeline::makePrimitiveState()
|
||||||
return primitiveState;
|
return primitiveState;
|
||||||
}
|
}
|
||||||
|
|
||||||
WGPUDepthStencilState WgPipeline::makeDepthStencilState(WGPUCompareFunction compare, WGPUStencilOperation operation)
|
WGPUDepthStencilState WgRenderPipeline::makeDepthStencilState(WGPUCompareFunction compare, WGPUStencilOperation operation)
|
||||||
{
|
{
|
||||||
WGPUDepthStencilState depthStencilState{};
|
WGPUDepthStencilState depthStencilState{};
|
||||||
depthStencilState.nextInChain = nullptr;
|
depthStencilState.nextInChain = nullptr;
|
||||||
|
@ -390,7 +439,7 @@ WGPUDepthStencilState WgPipeline::makeDepthStencilState(WGPUCompareFunction comp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUMultisampleState WgPipeline::makeMultisampleState()
|
WGPUMultisampleState WgRenderPipeline::makeMultisampleState()
|
||||||
{
|
{
|
||||||
WGPUMultisampleState multisampleState{};
|
WGPUMultisampleState multisampleState{};
|
||||||
multisampleState.nextInChain = nullptr;
|
multisampleState.nextInChain = nullptr;
|
||||||
|
@ -401,7 +450,7 @@ WGPUMultisampleState WgPipeline::makeMultisampleState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WGPUFragmentState WgPipeline::makeFragmentState(WGPUShaderModule shaderModule, WGPUColorTargetState* targets, uint32_t size)
|
WGPUFragmentState WgRenderPipeline::makeFragmentState(WGPUShaderModule shaderModule, WGPUColorTargetState* targets, uint32_t size)
|
||||||
{
|
{
|
||||||
WGPUFragmentState fragmentState{};
|
WGPUFragmentState fragmentState{};
|
||||||
fragmentState.nextInChain = nullptr;
|
fragmentState.nextInChain = nullptr;
|
||||||
|
@ -414,34 +463,7 @@ WGPUFragmentState WgPipeline::makeFragmentState(WGPUShaderModule shaderModule, W
|
||||||
return fragmentState;
|
return fragmentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WGPURenderPipeline WgRenderPipeline::createRenderPipeline(WGPUDevice device,
|
||||||
WGPUPipelineLayout WgPipeline::createPipelineLayout(WGPUDevice device, const WGPUBindGroupLayout* bindGroupLayouts, uint32_t count)
|
|
||||||
{
|
|
||||||
WGPUPipelineLayoutDescriptor pipelineLayoutDesc{};
|
|
||||||
pipelineLayoutDesc.nextInChain = nullptr;
|
|
||||||
pipelineLayoutDesc.label = "The Pipeline layout";
|
|
||||||
pipelineLayoutDesc.bindGroupLayoutCount = count;
|
|
||||||
pipelineLayoutDesc.bindGroupLayouts = bindGroupLayouts;
|
|
||||||
return wgpuDeviceCreatePipelineLayout(device, &pipelineLayoutDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WGPUShaderModule WgPipeline::createShaderModule(WGPUDevice device, const char* code, const char* label)
|
|
||||||
{
|
|
||||||
WGPUShaderModuleWGSLDescriptor shaderModuleWGSLDesc{};
|
|
||||||
shaderModuleWGSLDesc.chain.next = nullptr;
|
|
||||||
shaderModuleWGSLDesc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
|
||||||
shaderModuleWGSLDesc.code = code;
|
|
||||||
WGPUShaderModuleDescriptor shaderModuleDesc{};
|
|
||||||
shaderModuleDesc.nextInChain = &shaderModuleWGSLDesc.chain;
|
|
||||||
shaderModuleDesc.label = label;
|
|
||||||
shaderModuleDesc.hintCount = 0;
|
|
||||||
shaderModuleDesc.hints = nullptr;
|
|
||||||
return wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WGPURenderPipeline WgPipeline::createRenderPipeline(WGPUDevice device,
|
|
||||||
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
||||||
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
||||||
WGPUPipelineLayout pipelineLayout, WGPUShaderModule shaderModule,
|
WGPUPipelineLayout pipelineLayout, WGPUShaderModule shaderModule,
|
||||||
|
@ -470,22 +492,7 @@ WGPURenderPipeline WgPipeline::createRenderPipeline(WGPUDevice device,
|
||||||
return wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
|
return wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WgRenderPipeline::destroyRenderPipeline(WGPURenderPipeline& renderPipeline)
|
||||||
void WgPipeline::destroyPipelineLayout(WGPUPipelineLayout& pipelineLayout)
|
|
||||||
{
|
|
||||||
if (pipelineLayout) wgpuPipelineLayoutRelease(pipelineLayout);
|
|
||||||
pipelineLayout = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WgPipeline::destroyShaderModule(WGPUShaderModule& shaderModule)
|
|
||||||
{
|
|
||||||
if (shaderModule) wgpuShaderModuleRelease(shaderModule);
|
|
||||||
shaderModule = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WgPipeline::destroyRenderPipeline(WGPURenderPipeline& renderPipeline)
|
|
||||||
{
|
{
|
||||||
if (renderPipeline) wgpuRenderPipelineRelease(renderPipeline);
|
if (renderPipeline) wgpuRenderPipelineRelease(renderPipeline);
|
||||||
renderPipeline = nullptr;
|
renderPipeline = nullptr;
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgRender.h"
|
#include "tvgRender.h"
|
||||||
|
|
||||||
|
struct WgPipelines;
|
||||||
|
|
||||||
struct WgContext {
|
struct WgContext {
|
||||||
WGPUInstance instance{};
|
WGPUInstance instance{};
|
||||||
WGPUAdapter adapter{};
|
WGPUAdapter adapter{};
|
||||||
|
@ -37,6 +39,8 @@ struct WgContext {
|
||||||
WGPUFeatureName featureNames[32]{};
|
WGPUFeatureName featureNames[32]{};
|
||||||
WGPUAdapterProperties adapterProperties{};
|
WGPUAdapterProperties adapterProperties{};
|
||||||
WGPUSupportedLimits supportedLimits{};
|
WGPUSupportedLimits supportedLimits{};
|
||||||
|
|
||||||
|
WgPipelines* pipelines{}; // external handle (do not release)
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void release();
|
void release();
|
||||||
|
@ -70,17 +74,29 @@ struct WgBindGroup
|
||||||
struct WgPipeline
|
struct WgPipeline
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
WGPUPipelineLayout mPipelineLayout{};
|
||||||
|
WGPUShaderModule mShaderModule{};
|
||||||
|
public:
|
||||||
|
virtual void initialize(WGPUDevice device) = 0;
|
||||||
|
virtual void release();
|
||||||
|
|
||||||
|
static WGPUPipelineLayout createPipelineLayout(WGPUDevice device, const WGPUBindGroupLayout* bindGroupLayouts, uint32_t count);
|
||||||
|
static WGPUShaderModule createShaderModule(WGPUDevice device, const char* code, const char* label);
|
||||||
|
static void destroyPipelineLayout(WGPUPipelineLayout& pipelineLayout);
|
||||||
|
static void destroyShaderModule(WGPUShaderModule& shaderModule);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WgRenderPipeline: public WgPipeline
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
WGPURenderPipeline mRenderPipeline{};
|
||||||
void allocate(WGPUDevice device,
|
void allocate(WGPUDevice device,
|
||||||
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
||||||
WGPUBindGroupLayout bindGroupLayouts[], uint32_t bindGroupsCount,
|
WGPUBindGroupLayout bindGroupLayouts[], uint32_t bindGroupsCount,
|
||||||
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
||||||
const char* shaderSource, const char* shaderLabel, const char* pipelineLabel);
|
const char* shaderSource, const char* shaderLabel, const char* pipelineLabel);
|
||||||
WGPUPipelineLayout mPipelineLayout{};
|
|
||||||
WGPUShaderModule mShaderModule{};
|
|
||||||
WGPURenderPipeline mRenderPipeline{};
|
|
||||||
public:
|
public:
|
||||||
virtual void initialize(WGPUDevice device) = 0;
|
void release() override;
|
||||||
virtual void release();
|
|
||||||
void set(WGPURenderPassEncoder renderPassEncoder);
|
void set(WGPURenderPassEncoder renderPassEncoder);
|
||||||
|
|
||||||
static WGPUBlendState makeBlendState();
|
static WGPUBlendState makeBlendState();
|
||||||
|
@ -92,15 +108,11 @@ public:
|
||||||
static WGPUMultisampleState makeMultisampleState();
|
static WGPUMultisampleState makeMultisampleState();
|
||||||
static WGPUFragmentState makeFragmentState(WGPUShaderModule shaderModule, WGPUColorTargetState* targets, uint32_t size);
|
static WGPUFragmentState makeFragmentState(WGPUShaderModule shaderModule, WGPUColorTargetState* targets, uint32_t size);
|
||||||
|
|
||||||
static WGPUPipelineLayout createPipelineLayout(WGPUDevice device, const WGPUBindGroupLayout* bindGroupLayouts, uint32_t count);
|
|
||||||
static WGPUShaderModule createShaderModule(WGPUDevice device, const char* code, const char* label);
|
|
||||||
static WGPURenderPipeline createRenderPipeline(WGPUDevice device,
|
static WGPURenderPipeline createRenderPipeline(WGPUDevice device,
|
||||||
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
WGPUVertexBufferLayout vertexBufferLayouts[], uint32_t attribsCount,
|
||||||
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
WGPUCompareFunction stencilCompareFunction, WGPUStencilOperation stencilOperation,
|
||||||
WGPUPipelineLayout pipelineLayout, WGPUShaderModule shaderModule,
|
WGPUPipelineLayout pipelineLayout, WGPUShaderModule shaderModule,
|
||||||
const char* pipelineLabel);
|
const char* pipelineLabel);
|
||||||
static void destroyPipelineLayout(WGPUPipelineLayout& pipelineLayout);
|
|
||||||
static void destroyShaderModule(WGPUShaderModule& shaderModule);
|
|
||||||
static void destroyRenderPipeline(WGPURenderPipeline& renderPipeline);
|
static void destroyRenderPipeline(WGPURenderPipeline& renderPipeline);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,8 @@ void WgPipelineBlit::initialize(WGPUDevice device)
|
||||||
|
|
||||||
// bind groups and layouts
|
// bind groups and layouts
|
||||||
WGPUBindGroupLayout bindGroupLayouts[] = {
|
WGPUBindGroupLayout bindGroupLayouts[] = {
|
||||||
WgBindGroupBlit::getLayout(device)
|
WgBindGroupBlit::getLayout(device),
|
||||||
|
WgBindGroupOpacity::getLayout(device)
|
||||||
};
|
};
|
||||||
|
|
||||||
// stencil function
|
// stencil function
|
||||||
|
@ -326,35 +327,39 @@ void WgPipelineComposition::initialize(WGPUDevice device, const char* shaderSrc)
|
||||||
// pipelines
|
// pipelines
|
||||||
//************************************************************************
|
//************************************************************************
|
||||||
|
|
||||||
void WgPipelines::initialize(WGPUDevice device)
|
void WgPipelines::initialize(WgContext& context)
|
||||||
{
|
{
|
||||||
fillShape.initialize(device);
|
fillShape.initialize(context.device);
|
||||||
fillStroke.initialize(device);
|
fillStroke.initialize(context.device);
|
||||||
solid.initialize(device);
|
solid.initialize(context.device);
|
||||||
linear.initialize(device);
|
linear.initialize(context.device);
|
||||||
radial.initialize(device);
|
radial.initialize(context.device);
|
||||||
image.initialize(device);
|
image.initialize(context.device);
|
||||||
blit.initialize(device);
|
blit.initialize(context.device);
|
||||||
blitColor.initialize(device);
|
blitColor.initialize(context.device);
|
||||||
// composition pipelines
|
// composition pipelines
|
||||||
compAlphaMask.initialize(device, cShaderSource_PipelineCompAlphaMask);
|
compAlphaMask.initialize(context.device, cShaderSource_PipelineCompAlphaMask);
|
||||||
compInvAlphaMask.initialize(device, cShaderSource_PipelineCompInvAlphaMask);
|
compInvAlphaMask.initialize(context.device, cShaderSource_PipelineCompInvAlphaMask);
|
||||||
compLumaMask.initialize(device, cShaderSource_PipelineCompLumaMask);
|
compLumaMask.initialize(context.device, cShaderSource_PipelineCompLumaMask);
|
||||||
compInvLumaMask.initialize(device, cShaderSource_PipelineCompInvLumaMask);
|
compInvLumaMask.initialize(context.device, cShaderSource_PipelineCompInvLumaMask);
|
||||||
compAddMask.initialize(device, cShaderSource_PipelineCompAddMask);
|
compAddMask.initialize(context.device, cShaderSource_PipelineCompAddMask);
|
||||||
compSubtractMask.initialize(device, cShaderSource_PipelineCompSubtractMask);
|
compSubtractMask.initialize(context.device, cShaderSource_PipelineCompSubtractMask);
|
||||||
compIntersectMask.initialize(device, cShaderSource_PipelineCompIntersectMask);
|
compIntersectMask.initialize(context.device, cShaderSource_PipelineCompIntersectMask);
|
||||||
compDifferenceMask.initialize(device, cShaderSource_PipelineCompDifferenceMask);
|
compDifferenceMask.initialize(context.device, cShaderSource_PipelineCompDifferenceMask);
|
||||||
|
// store pipelines to context
|
||||||
|
context.pipelines = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgPipelines::release()
|
void WgPipelines::release()
|
||||||
{
|
{
|
||||||
WgBindGroupBlit::releaseLayout();
|
WgBindGroupBlit::releaseLayout();
|
||||||
|
WgBindGroupOpacity::releaseLayout();
|
||||||
WgBindGroupPicture::releaseLayout();
|
WgBindGroupPicture::releaseLayout();
|
||||||
WgBindGroupRadialGradient::releaseLayout();
|
WgBindGroupRadialGradient::releaseLayout();
|
||||||
WgBindGroupLinearGradient::releaseLayout();
|
WgBindGroupLinearGradient::releaseLayout();
|
||||||
WgBindGroupSolidColor::releaseLayout();
|
WgBindGroupSolidColor::releaseLayout();
|
||||||
|
WgBindGroupPaint::releaseLayout();
|
||||||
WgBindGroupCanvas::releaseLayout();
|
WgBindGroupCanvas::releaseLayout();
|
||||||
compDifferenceMask.release();
|
compDifferenceMask.release();
|
||||||
compIntersectMask.release();
|
compIntersectMask.release();
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
#include "tvgWgBindGroups.h"
|
#include "tvgWgBindGroups.h"
|
||||||
|
|
||||||
struct WgPipelineFillShape: public WgPipeline
|
struct WgPipelineFillShape: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint)
|
||||||
|
@ -36,7 +36,7 @@ struct WgPipelineFillShape: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineFillStroke: public WgPipeline
|
struct WgPipelineFillStroke: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint)
|
||||||
|
@ -47,7 +47,7 @@ struct WgPipelineFillStroke: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineSolid: public WgPipeline
|
struct WgPipelineSolid: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas,WgBindGroupPaint& groupPaint, WgBindGroupSolidColor& groupSolid)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas,WgBindGroupPaint& groupPaint, WgBindGroupSolidColor& groupSolid)
|
||||||
|
@ -59,7 +59,7 @@ struct WgPipelineSolid: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineLinear: public WgPipeline
|
struct WgPipelineLinear: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint, WgBindGroupLinearGradient& groupLinear)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint, WgBindGroupLinearGradient& groupLinear)
|
||||||
|
@ -71,7 +71,7 @@ struct WgPipelineLinear: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineRadial: public WgPipeline
|
struct WgPipelineRadial: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint, WgBindGroupRadialGradient& groupRadial)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint, WgBindGroupRadialGradient& groupRadial)
|
||||||
|
@ -83,7 +83,7 @@ struct WgPipelineRadial: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineImage: public WgPipeline
|
struct WgPipelineImage: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint, WgBindGroupPicture& groupPicture)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupCanvas& groupCanvas, WgBindGroupPaint& groupPaint, WgBindGroupPicture& groupPicture)
|
||||||
|
@ -95,7 +95,20 @@ struct WgPipelineImage: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineBlit: public WgPipeline
|
struct WgPipelineBlit: public WgRenderPipeline
|
||||||
|
{
|
||||||
|
void initialize(WGPUDevice device) override;
|
||||||
|
void use(WGPURenderPassEncoder encoder,
|
||||||
|
WgBindGroupBlit& groupBlit,
|
||||||
|
WgBindGroupOpacity& groupOpacity)
|
||||||
|
{
|
||||||
|
set(encoder);
|
||||||
|
groupBlit.set(encoder, 0);
|
||||||
|
groupOpacity.set(encoder, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WgPipelineBlitColor: public WgRenderPipeline
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override;
|
void initialize(WGPUDevice device) override;
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupBlit& groupBlit)
|
void use(WGPURenderPassEncoder encoder, WgBindGroupBlit& groupBlit)
|
||||||
|
@ -105,17 +118,7 @@ struct WgPipelineBlit: public WgPipeline
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WgPipelineBlitColor: public WgPipeline
|
struct WgPipelineComposition: public WgRenderPipeline
|
||||||
{
|
|
||||||
void initialize(WGPUDevice device) override;
|
|
||||||
void use(WGPURenderPassEncoder encoder, WgBindGroupBlit& groupBlit)
|
|
||||||
{
|
|
||||||
set(encoder);
|
|
||||||
groupBlit.set(encoder, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WgPipelineComposition: public WgPipeline
|
|
||||||
{
|
{
|
||||||
void initialize(WGPUDevice device) override {};
|
void initialize(WGPUDevice device) override {};
|
||||||
void initialize(WGPUDevice device, const char* shaderSrc);
|
void initialize(WGPUDevice device, const char* shaderSrc);
|
||||||
|
@ -147,7 +150,7 @@ struct WgPipelines
|
||||||
WgPipelineComposition compIntersectMask;
|
WgPipelineComposition compIntersectMask;
|
||||||
WgPipelineComposition compDifferenceMask;
|
WgPipelineComposition compDifferenceMask;
|
||||||
|
|
||||||
void initialize(WGPUDevice device);
|
void initialize(WgContext& context);
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
WgPipelineComposition* getCompositionPipeline(CompositeMethod method);
|
WgPipelineComposition* getCompositionPipeline(CompositeMethod method);
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "tvgWgRenderTarget.h"
|
#include "tvgWgRenderTarget.h"
|
||||||
|
|
||||||
void WgRenderTarget::initialize(WgContext& context, WgPipelines& pipelines, uint32_t w, uint32_t h)
|
void WgRenderTarget::initialize(WgContext& context, uint32_t w, uint32_t h)
|
||||||
{
|
{
|
||||||
release(context);
|
release(context);
|
||||||
// sampler descriptor
|
// sampler descriptor
|
||||||
|
@ -45,7 +45,7 @@ void WgRenderTarget::initialize(WgContext& context, WgPipelines& pipelines, uint
|
||||||
WGPUTextureDescriptor textureDescColor{};
|
WGPUTextureDescriptor textureDescColor{};
|
||||||
textureDescColor.nextInChain = nullptr;
|
textureDescColor.nextInChain = nullptr;
|
||||||
textureDescColor.label = "The target texture color";
|
textureDescColor.label = "The target texture color";
|
||||||
textureDescColor.usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst;
|
textureDescColor.usage = WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst | WGPUTextureUsage_StorageBinding;
|
||||||
textureDescColor.dimension = WGPUTextureDimension_2D;
|
textureDescColor.dimension = WGPUTextureDimension_2D;
|
||||||
textureDescColor.size = { w, h, 1 };
|
textureDescColor.size = { w, h, 1 };
|
||||||
textureDescColor.format = WGPUTextureFormat_BGRA8Unorm;
|
textureDescColor.format = WGPUTextureFormat_BGRA8Unorm;
|
||||||
|
@ -103,7 +103,7 @@ void WgRenderTarget::initialize(WgContext& context, WgPipelines& pipelines, uint
|
||||||
WgGeometryData geometryDataWnd;
|
WgGeometryData geometryDataWnd;
|
||||||
geometryDataWnd.appendBlitBox();
|
geometryDataWnd.appendBlitBox();
|
||||||
mMeshDataCanvasWnd.update(context, &geometryDataWnd);
|
mMeshDataCanvasWnd.update(context, &geometryDataWnd);
|
||||||
mPipelines = &pipelines;
|
mPipelines = context.pipelines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -248,10 +248,10 @@ void WgRenderTarget::renderPicture(WgRenderDataPicture* renderData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgRenderTarget::blit(WgContext& context, WgRenderTarget* renderTargetSrc)
|
void WgRenderTarget::blit(WgContext& context, WgRenderTarget* renderTargetSrc, WgBindGroupOpacity* mBindGroupOpacity)
|
||||||
{
|
{
|
||||||
assert(mRenderPassEncoder);
|
assert(mRenderPassEncoder);
|
||||||
mPipelines->blit.use(mRenderPassEncoder, renderTargetSrc->bindGroupBlit);
|
mPipelines->blit.use(mRenderPassEncoder, renderTargetSrc->bindGroupBlit, *mBindGroupOpacity);
|
||||||
mMeshDataCanvasWnd.drawImage(mRenderPassEncoder);
|
mMeshDataCanvasWnd.drawImage(mRenderPassEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,3 +272,37 @@ void WgRenderTarget::compose(WgContext& context, WgRenderTarget* renderTargetSrc
|
||||||
pipeline->use(mRenderPassEncoder, renderTargetSrc->bindGroupBlit, renderTargetMsk->bindGroupBlit);
|
pipeline->use(mRenderPassEncoder, renderTargetSrc->bindGroupBlit, renderTargetMsk->bindGroupBlit);
|
||||||
mMeshDataCanvasWnd.drawImage(mRenderPassEncoder);
|
mMeshDataCanvasWnd.drawImage(mRenderPassEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// render terget pool
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
WgRenderTarget* WgRenderTargetPool::allocate(WgContext& context, uint32_t w, uint32_t h)
|
||||||
|
{
|
||||||
|
WgRenderTarget* renderTarget{};
|
||||||
|
if (mPool.count > 0) {
|
||||||
|
renderTarget = mPool.last();
|
||||||
|
mPool.pop();
|
||||||
|
} else {
|
||||||
|
renderTarget = new WgRenderTarget;
|
||||||
|
renderTarget->initialize(context, w, h);
|
||||||
|
mList.push(renderTarget);
|
||||||
|
}
|
||||||
|
return renderTarget;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void WgRenderTargetPool::free(WgContext& context, WgRenderTarget* renderTarget) {
|
||||||
|
mPool.push(renderTarget);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void WgRenderTargetPool::release(WgContext& context)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < mList.count; i++) {
|
||||||
|
mList[i]->release(context);
|
||||||
|
delete mList[i];
|
||||||
|
}
|
||||||
|
mList.clear();
|
||||||
|
mPool.clear();
|
||||||
|
};
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
WGPUTextureView textureViewStencil{};
|
WGPUTextureView textureViewStencil{};
|
||||||
WgBindGroupBlit bindGroupBlit;
|
WgBindGroupBlit bindGroupBlit;
|
||||||
public:
|
public:
|
||||||
void initialize(WgContext& context, WgPipelines& pipelines, uint32_t w, uint32_t h);
|
void initialize(WgContext& context, uint32_t w, uint32_t h);
|
||||||
void release(WgContext& context);
|
void release(WgContext& context);
|
||||||
|
|
||||||
void beginRenderPass(WGPUCommandEncoder commandEncoder, WGPUTextureView colorAttachement, bool clear);
|
void beginRenderPass(WGPUCommandEncoder commandEncoder, WGPUTextureView colorAttachement, bool clear);
|
||||||
|
@ -54,9 +54,21 @@ public:
|
||||||
void renderStroke(WgRenderDataShape* renderData);
|
void renderStroke(WgRenderDataShape* renderData);
|
||||||
void renderPicture(WgRenderDataPicture* renderData);
|
void renderPicture(WgRenderDataPicture* renderData);
|
||||||
|
|
||||||
void blit(WgContext& context, WgRenderTarget* renderTargetSrc);
|
void blit(WgContext& context, WgRenderTarget* renderTargetSrc, WgBindGroupOpacity* bindGroupOpacity);
|
||||||
void blitColor(WgContext& context, WgRenderTarget* renderTargetSrc);
|
void blitColor(WgContext& context, WgRenderTarget* renderTargetSrc);
|
||||||
void compose(WgContext& context, WgRenderTarget* renderTargetSrc, WgRenderTarget* renderTargetMsk, CompositeMethod method);
|
void compose(WgContext& context, WgRenderTarget* renderTargetSrc, WgRenderTarget* renderTargetMsk, CompositeMethod method);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class WgRenderTargetPool {
|
||||||
|
private:
|
||||||
|
Array<WgRenderTarget*> mList;
|
||||||
|
Array<WgRenderTarget*> mPool;
|
||||||
|
public:
|
||||||
|
WgRenderTarget* allocate(WgContext& context, uint32_t w, uint32_t h);
|
||||||
|
void free(WgContext& context, WgRenderTarget* renderTarget);
|
||||||
|
void release(WgContext& context);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,18 +42,16 @@ WgRenderer::~WgRenderer()
|
||||||
void WgRenderer::initialize()
|
void WgRenderer::initialize()
|
||||||
{
|
{
|
||||||
mContext.initialize();
|
mContext.initialize();
|
||||||
mPipelines.initialize(mContext.device);
|
mPipelines.initialize(mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WgRenderer::release()
|
void WgRenderer::release()
|
||||||
{
|
{
|
||||||
// clear render targets
|
mCompositorStack.clear();
|
||||||
for (uint32_t i = 0; i < mRenderTargetPool.count; i++) {
|
mRenderTargetStack.clear();
|
||||||
mRenderTargetPool[i]->release(mContext);
|
mBindGroupOpacityPool.release();
|
||||||
delete mRenderTargetPool[i];
|
mRenderTargetPool.release(mContext);
|
||||||
}
|
|
||||||
mRenderTargetPool.clear();
|
|
||||||
mRenderTargetRoot.release(mContext);
|
mRenderTargetRoot.release(mContext);
|
||||||
mRenderTargetWnd.release(mContext);
|
mRenderTargetWnd.release(mContext);
|
||||||
if (mSwapChain) wgpuSwapChainRelease(mSwapChain);
|
if (mSwapChain) wgpuSwapChainRelease(mSwapChain);
|
||||||
|
@ -161,6 +159,7 @@ bool WgRenderer::postRender()
|
||||||
{
|
{
|
||||||
mRenderTargetRoot.endRenderPass();
|
mRenderTargetRoot.endRenderPass();
|
||||||
mRenderTargetStack.pop();
|
mRenderTargetStack.pop();
|
||||||
|
mBindGroupOpacityPool.reset();
|
||||||
mContext.executeCommandEncoder(mCommandEncoder);
|
mContext.executeCommandEncoder(mCommandEncoder);
|
||||||
wgpuCommandEncoderRelease(mCommandEncoder);
|
wgpuCommandEncoderRelease(mCommandEncoder);
|
||||||
return true;
|
return true;
|
||||||
|
@ -235,7 +234,7 @@ bool WgRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
|
||||||
mTargetSurface.w = w;
|
mTargetSurface.w = w;
|
||||||
mTargetSurface.h = h;
|
mTargetSurface.h = h;
|
||||||
|
|
||||||
mRenderTargetRoot.initialize(mContext, mPipelines, w, h);
|
mRenderTargetRoot.initialize(mContext, w, h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,8 +274,8 @@ bool WgRenderer::target(void* window, uint32_t w, uint32_t h)
|
||||||
mSwapChain = wgpuDeviceCreateSwapChain(mContext.device, mSurface, &swapChainDesc);
|
mSwapChain = wgpuDeviceCreateSwapChain(mContext.device, mSurface, &swapChainDesc);
|
||||||
assert(mSwapChain);
|
assert(mSwapChain);
|
||||||
|
|
||||||
mRenderTargetWnd.initialize(mContext, mPipelines, w, h);
|
mRenderTargetWnd.initialize(mContext, w, h);
|
||||||
mRenderTargetRoot.initialize(mContext, mPipelines, w, h);
|
mRenderTargetRoot.initialize(mContext, w, h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +297,7 @@ bool WgRenderer::beginComposite(TVG_UNUSED Compositor* cmp, TVG_UNUSED Composite
|
||||||
mRenderTargetStack.last()->endRenderPass();
|
mRenderTargetStack.last()->endRenderPass();
|
||||||
|
|
||||||
// create new render target and begin new render pass
|
// create new render target and begin new render pass
|
||||||
WgRenderTarget* renderTarget = allocateRenderTarget();
|
WgRenderTarget* renderTarget = mRenderTargetPool.allocate(mContext, mTargetSurface.w, mTargetSurface.h);
|
||||||
renderTarget->beginRenderPass(mCommandEncoder, true);
|
renderTarget->beginRenderPass(mCommandEncoder, true);
|
||||||
mRenderTargetStack.push(renderTarget);
|
mRenderTargetStack.push(renderTarget);
|
||||||
|
|
||||||
|
@ -319,10 +318,13 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp)
|
||||||
// apply current render target
|
// apply current render target
|
||||||
WgRenderTarget* renderTarget = mRenderTargetStack.last();
|
WgRenderTarget* renderTarget = mRenderTargetStack.last();
|
||||||
renderTarget->beginRenderPass(mCommandEncoder, false);
|
renderTarget->beginRenderPass(mCommandEncoder, false);
|
||||||
renderTarget->blit(mContext, renderTargetSrc);
|
|
||||||
|
// blit scene to current render tartget
|
||||||
|
WgBindGroupOpacity* mBindGroupOpacity = mBindGroupOpacityPool.allocate(mContext, cmp->opacity);
|
||||||
|
renderTarget->blit(mContext, renderTargetSrc, mBindGroupOpacity);
|
||||||
|
|
||||||
// back render targets to the pool
|
// back render targets to the pool
|
||||||
releaseRenderTarget(renderTargetSrc);
|
mRenderTargetPool.free(mContext, renderTargetSrc);
|
||||||
} else {
|
} else {
|
||||||
// end current render pass
|
// end current render pass
|
||||||
mRenderTargetStack.last()->endRenderPass();
|
mRenderTargetStack.last()->endRenderPass();
|
||||||
|
@ -339,8 +341,8 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp)
|
||||||
renderTarget->compose(mContext, renderTargetSrc, renderTargetMsk, cmp->method);
|
renderTarget->compose(mContext, renderTargetSrc, renderTargetMsk, cmp->method);
|
||||||
|
|
||||||
// back render targets to the pool
|
// back render targets to the pool
|
||||||
releaseRenderTarget(renderTargetSrc);
|
mRenderTargetPool.free(mContext, renderTargetSrc);
|
||||||
releaseRenderTarget(renderTargetMsk);
|
mRenderTargetPool.free(mContext, renderTargetMsk);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete current compositor
|
// delete current compositor
|
||||||
|
@ -351,26 +353,6 @@ bool WgRenderer::endComposite(TVG_UNUSED Compositor* cmp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WgRenderTarget* WgRenderer::allocateRenderTarget()
|
|
||||||
{
|
|
||||||
WgRenderTarget* renderTarget = nullptr;
|
|
||||||
if (mRenderTargetPool.count > 0) {
|
|
||||||
renderTarget = mRenderTargetPool.last();
|
|
||||||
mRenderTargetPool.pop();
|
|
||||||
} else {
|
|
||||||
renderTarget = new WgRenderTarget;
|
|
||||||
renderTarget->initialize(mContext, mPipelines, mTargetSurface.w, mTargetSurface.h);
|
|
||||||
}
|
|
||||||
return renderTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WgRenderer::releaseRenderTarget(WgRenderTarget* renderTarget)
|
|
||||||
{
|
|
||||||
mRenderTargetPool.push(renderTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WgRenderer* WgRenderer::gen()
|
WgRenderer* WgRenderer::gen()
|
||||||
{
|
{
|
||||||
return new WgRenderer();
|
return new WgRenderer();
|
||||||
|
|
|
@ -62,12 +62,12 @@ public:
|
||||||
|
|
||||||
// render handles
|
// render handles
|
||||||
WGPUCommandEncoder mCommandEncoder{};
|
WGPUCommandEncoder mCommandEncoder{};
|
||||||
Array<WgRenderTarget*> mRenderTargetStack;
|
|
||||||
Array<WgRenderTarget*> mRenderTargetPool;
|
|
||||||
Array<Compositor*> mCompositorStack;
|
Array<Compositor*> mCompositorStack;
|
||||||
|
Array<WgRenderTarget*> mRenderTargetStack;
|
||||||
|
|
||||||
WgRenderTarget* allocateRenderTarget();
|
// render object pools
|
||||||
void releaseRenderTarget(WgRenderTarget* renderTarget);
|
WgRenderTargetPool mRenderTargetPool;
|
||||||
|
WgBindGroupOpacityPool mBindGroupOpacityPool;
|
||||||
private:
|
private:
|
||||||
WgContext mContext;
|
WgContext mContext;
|
||||||
WgPipelines mPipelines;
|
WgPipelines mPipelines;
|
||||||
|
|
|
@ -352,8 +352,9 @@ struct VertexOutput {
|
||||||
@location(0) texCoord: vec2f
|
@location(0) texCoord: vec2f
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(0) @binding(0) var uSamplerSrc : sampler;
|
@group(0) @binding(0) var uSamplerSrc : sampler;
|
||||||
@group(0) @binding(1) var uTextureViewSrc : texture_2d<f32>;
|
@group(0) @binding(1) var uTextureViewSrc : texture_2d<f32>;
|
||||||
|
@group(1) @binding(0) var<uniform> uOpacity : f32;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(in: VertexInput) -> VertexOutput {
|
fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
|
@ -366,7 +367,9 @@ fn vs_main(in: VertexInput) -> VertexOutput {
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4f {
|
||||||
return textureSample(uTextureViewSrc, uSamplerSrc, in.texCoord.xy);
|
let color: vec4f = textureSample(uTextureViewSrc, uSamplerSrc, in.texCoord.xy);
|
||||||
|
return vec4f(color.rgb, uOpacity);
|
||||||
|
//return vec4f(color.rgb, 0.5);
|
||||||
};
|
};
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue