[Flutter GPU] Added support to set Scissor. (flutter/engine#56302)
Added support to set scissors. This resolves issue #157199
This commit is contained in:
parent
69da421d98
commit
4705535548
@ -150,6 +150,18 @@ base class SamplerOptions {
|
|||||||
SamplerAddressMode heightAddressMode;
|
SamplerAddressMode heightAddressMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base class Scissor {
|
||||||
|
Scissor({this.x = 0, this.y = 0, this.width = 0, this.height = 0});
|
||||||
|
|
||||||
|
int x, y, width, height;
|
||||||
|
|
||||||
|
void _validate() {
|
||||||
|
if (x < 0 || y < 0 || width < 0 || height < 0) {
|
||||||
|
throw Exception("Invalid values for scissor. All values should be positive.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
base class RenderTarget {
|
base class RenderTarget {
|
||||||
const RenderTarget(
|
const RenderTarget(
|
||||||
{this.colorAttachments = const <ColorAttachment>[],
|
{this.colorAttachments = const <ColorAttachment>[],
|
||||||
@ -326,6 +338,14 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
|||||||
targetFace.index);
|
targetFace.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setScissor(Scissor scissor) {
|
||||||
|
assert(() {
|
||||||
|
scissor._validate();
|
||||||
|
return true;
|
||||||
|
}());
|
||||||
|
_setScissor(scissor.x, scissor.y, scissor.width, scissor.height);
|
||||||
|
}
|
||||||
|
|
||||||
void setCullMode(CullMode cullMode) {
|
void setCullMode(CullMode cullMode) {
|
||||||
_setCullMode(cullMode.index);
|
_setCullMode(cullMode.index);
|
||||||
}
|
}
|
||||||
@ -478,6 +498,14 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
|||||||
int writeMask,
|
int writeMask,
|
||||||
int target_face);
|
int target_face);
|
||||||
|
|
||||||
|
@Native<Void Function(Pointer<Void>, Int, Int, Int, Int)>(
|
||||||
|
symbol: 'InternalFlutterGpu_RenderPass_SetScissor')
|
||||||
|
external void _setScissor(
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
@Native<Void Function(Pointer<Void>, Int)>(
|
@Native<Void Function(Pointer<Void>, Int)>(
|
||||||
symbol: 'InternalFlutterGpu_RenderPass_SetCullMode')
|
symbol: 'InternalFlutterGpu_RenderPass_SetCullMode')
|
||||||
external void _setCullMode(int cullMode);
|
external void _setCullMode(int cullMode);
|
||||||
|
@ -207,6 +207,10 @@ bool RenderPass::Draw() {
|
|||||||
|
|
||||||
render_pass_->SetStencilReference(stencil_reference);
|
render_pass_->SetStencilReference(stencil_reference);
|
||||||
|
|
||||||
|
if (scissor.has_value()) {
|
||||||
|
render_pass_->SetScissor(scissor.value());
|
||||||
|
}
|
||||||
|
|
||||||
bool result = render_pass_->Draw().ok();
|
bool result = render_pass_->Draw().ok();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -536,6 +540,14 @@ void InternalFlutterGpu_RenderPass_SetStencilReference(
|
|||||||
wrapper->stencil_reference = static_cast<uint32_t>(stencil_reference);
|
wrapper->stencil_reference = static_cast<uint32_t>(stencil_reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InternalFlutterGpu_RenderPass_SetScissor(flutter::gpu::RenderPass* wrapper,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height) {
|
||||||
|
wrapper->scissor = impeller::TRect<int64_t>::MakeXYWH(x, y, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void InternalFlutterGpu_RenderPass_SetStencilConfig(
|
void InternalFlutterGpu_RenderPass_SetStencilConfig(
|
||||||
flutter::gpu::RenderPass* wrapper,
|
flutter::gpu::RenderPass* wrapper,
|
||||||
int stencil_compare_operation,
|
int stencil_compare_operation,
|
||||||
|
@ -74,6 +74,7 @@ class RenderPass : public RefCountedDartWrappable<RenderPass> {
|
|||||||
size_t element_count = 0;
|
size_t element_count = 0;
|
||||||
|
|
||||||
uint32_t stencil_reference = 0;
|
uint32_t stencil_reference = 0;
|
||||||
|
std::optional<impeller::TRect<int64_t>> scissor;
|
||||||
|
|
||||||
// Helper flag to determine whether the vertex_count should override the
|
// Helper flag to determine whether the vertex_count should override the
|
||||||
// element count. The index count takes precedent.
|
// element count. The index count takes precedent.
|
||||||
@ -234,6 +235,14 @@ extern void InternalFlutterGpu_RenderPass_SetStencilConfig(
|
|||||||
int write_mask,
|
int write_mask,
|
||||||
int target);
|
int target);
|
||||||
|
|
||||||
|
FLUTTER_GPU_EXPORT
|
||||||
|
extern void InternalFlutterGpu_RenderPass_SetScissor(
|
||||||
|
flutter::gpu::RenderPass* wrapper,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
FLUTTER_GPU_EXPORT
|
FLUTTER_GPU_EXPORT
|
||||||
extern void InternalFlutterGpu_RenderPass_SetCullMode(
|
extern void InternalFlutterGpu_RenderPass_SetCullMode(
|
||||||
flutter::gpu::RenderPass* wrapper,
|
flutter::gpu::RenderPass* wrapper,
|
||||||
|
@ -736,4 +736,78 @@ void main() async {
|
|||||||
await comparer.addGoldenImage(
|
await comparer.addGoldenImage(
|
||||||
image, 'flutter_gpu_test_hexgon_line_strip.png');
|
image, 'flutter_gpu_test_hexgon_line_strip.png');
|
||||||
}, skip: !impellerEnabled);
|
}, skip: !impellerEnabled);
|
||||||
|
|
||||||
|
// Renders the middle part triangle using scissor.
|
||||||
|
test('Can render portion of the triangle using scissor', () async {
|
||||||
|
final state = createSimpleRenderPass();
|
||||||
|
|
||||||
|
final gpu.RenderPipeline pipeline = createUnlitRenderPipeline();
|
||||||
|
state.renderPass.bindPipeline(pipeline);
|
||||||
|
|
||||||
|
// Configure blending with defaults (just to test the bindings).
|
||||||
|
state.renderPass.setColorBlendEnable(true);
|
||||||
|
state.renderPass.setColorBlendEquation(gpu.ColorBlendEquation());
|
||||||
|
|
||||||
|
// Set primitive type.
|
||||||
|
state.renderPass.setPrimitiveType(gpu.PrimitiveType.triangle);
|
||||||
|
|
||||||
|
// Set scissor.
|
||||||
|
state.renderPass.setScissor(gpu.Scissor(x: 25, width: 50, height: 100));
|
||||||
|
|
||||||
|
final gpu.HostBuffer transients = gpu.gpuContext.createHostBuffer();
|
||||||
|
final gpu.BufferView vertices = transients.emplace(float32(<double>[
|
||||||
|
-1.0,
|
||||||
|
-1.0,
|
||||||
|
0.0,
|
||||||
|
1.0,
|
||||||
|
1.0,
|
||||||
|
-1.0]));
|
||||||
|
final gpu.BufferView vertInfoData = transients.emplace(float32(<double>[
|
||||||
|
1, 0, 0, 0, // mvp
|
||||||
|
0, 1, 0, 0, // mvp
|
||||||
|
0, 0, 1, 0, // mvp
|
||||||
|
0, 0, 0, 1, // mvp
|
||||||
|
0, 1, 0, 1, // color
|
||||||
|
]));
|
||||||
|
state.renderPass.bindVertexBuffer(vertices, 3);
|
||||||
|
|
||||||
|
final gpu.UniformSlot vertInfo =
|
||||||
|
pipeline.vertexShader.getUniformSlot('VertInfo');
|
||||||
|
state.renderPass.bindUniform(vertInfo, vertInfoData);
|
||||||
|
state.renderPass.draw();
|
||||||
|
|
||||||
|
state.commandBuffer.submit();
|
||||||
|
|
||||||
|
final ui.Image image = state.renderTexture.asImage();
|
||||||
|
await comparer.addGoldenImage(
|
||||||
|
image, 'flutter_gpu_test_scissor.png');
|
||||||
|
}, skip: !impellerEnabled);
|
||||||
|
|
||||||
|
test('RenderPass.setScissor doesnt throw for valid values',
|
||||||
|
() async {
|
||||||
|
final state = createSimpleRenderPass();
|
||||||
|
|
||||||
|
state.renderPass.setScissor(gpu.Scissor(x: 25, width: 50, height: 100));
|
||||||
|
state.renderPass.setScissor(gpu.Scissor(width: 50, height: 100));
|
||||||
|
}, skip: !impellerEnabled);
|
||||||
|
|
||||||
|
test('RenderPass.setScissor throws for invalid values', () async {
|
||||||
|
final state = createSimpleRenderPass();
|
||||||
|
|
||||||
|
try {
|
||||||
|
state.renderPass.setScissor(gpu.Scissor(x: -1, width: 50, height: 100));
|
||||||
|
fail('Exception not thrown for invalid scissor.');
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.toString(),
|
||||||
|
contains('Invalid values for scissor. All values should be positive.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
state.renderPass.setScissor(gpu.Scissor(width: 50, height: -100));
|
||||||
|
fail('Exception not thrown for invalid scissor.');
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.toString(),
|
||||||
|
contains('Invalid values for scissor. All values should be positive.'));
|
||||||
|
}
|
||||||
|
}, skip: !impellerEnabled);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user