[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;
|
||||
}
|
||||
|
||||
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 {
|
||||
const RenderTarget(
|
||||
{this.colorAttachments = const <ColorAttachment>[],
|
||||
@ -326,6 +338,14 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
||||
targetFace.index);
|
||||
}
|
||||
|
||||
void setScissor(Scissor scissor) {
|
||||
assert(() {
|
||||
scissor._validate();
|
||||
return true;
|
||||
}());
|
||||
_setScissor(scissor.x, scissor.y, scissor.width, scissor.height);
|
||||
}
|
||||
|
||||
void setCullMode(CullMode cullMode) {
|
||||
_setCullMode(cullMode.index);
|
||||
}
|
||||
@ -478,6 +498,14 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
||||
int writeMask,
|
||||
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)>(
|
||||
symbol: 'InternalFlutterGpu_RenderPass_SetCullMode')
|
||||
external void _setCullMode(int cullMode);
|
||||
|
@ -207,6 +207,10 @@ bool RenderPass::Draw() {
|
||||
|
||||
render_pass_->SetStencilReference(stencil_reference);
|
||||
|
||||
if (scissor.has_value()) {
|
||||
render_pass_->SetScissor(scissor.value());
|
||||
}
|
||||
|
||||
bool result = render_pass_->Draw().ok();
|
||||
|
||||
return result;
|
||||
@ -536,6 +540,14 @@ void InternalFlutterGpu_RenderPass_SetStencilReference(
|
||||
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(
|
||||
flutter::gpu::RenderPass* wrapper,
|
||||
int stencil_compare_operation,
|
||||
|
@ -74,6 +74,7 @@ class RenderPass : public RefCountedDartWrappable<RenderPass> {
|
||||
size_t element_count = 0;
|
||||
|
||||
uint32_t stencil_reference = 0;
|
||||
std::optional<impeller::TRect<int64_t>> scissor;
|
||||
|
||||
// Helper flag to determine whether the vertex_count should override the
|
||||
// element count. The index count takes precedent.
|
||||
@ -234,6 +235,14 @@ extern void InternalFlutterGpu_RenderPass_SetStencilConfig(
|
||||
int write_mask,
|
||||
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
|
||||
extern void InternalFlutterGpu_RenderPass_SetCullMode(
|
||||
flutter::gpu::RenderPass* wrapper,
|
||||
|
@ -736,4 +736,78 @@ void main() async {
|
||||
await comparer.addGoldenImage(
|
||||
image, 'flutter_gpu_test_hexgon_line_strip.png');
|
||||
}, 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