parent
c783ce2344
commit
f6b0598945
@ -168,6 +168,34 @@ base class Scissor {
|
||||
}
|
||||
}
|
||||
|
||||
base class DepthRange {
|
||||
DepthRange({this.zNear = 0.0, this.zFar = 1.0});
|
||||
|
||||
double zNear;
|
||||
double zFar;
|
||||
}
|
||||
|
||||
base class Viewport {
|
||||
Viewport({
|
||||
this.x = 0,
|
||||
this.y = 0,
|
||||
this.width = 0,
|
||||
this.height = 0,
|
||||
DepthRange? depthRange = null,
|
||||
}) : this.depthRange = depthRange ?? DepthRange();
|
||||
|
||||
int x, y, width, height;
|
||||
DepthRange depthRange;
|
||||
|
||||
void _validate() {
|
||||
if (x < 0 || y < 0 || width < 0 || height < 0) {
|
||||
throw Exception(
|
||||
"Invalid values for viewport. All values should be positive.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base class RenderTarget {
|
||||
const RenderTarget({
|
||||
this.colorAttachments = const <ColorAttachment>[],
|
||||
@ -346,6 +374,21 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
||||
_setDepthWriteEnable(enable);
|
||||
}
|
||||
|
||||
void setViewport(Viewport viewport) {
|
||||
assert(() {
|
||||
viewport._validate();
|
||||
return true;
|
||||
}());
|
||||
_setViewport(
|
||||
viewport.x,
|
||||
viewport.y,
|
||||
viewport.width,
|
||||
viewport.height,
|
||||
viewport.depthRange.zNear,
|
||||
viewport.depthRange.zFar,
|
||||
);
|
||||
}
|
||||
|
||||
void setDepthCompareOperation(CompareFunction compareFunction) {
|
||||
_setDepthCompareOperation(compareFunction.index);
|
||||
}
|
||||
@ -508,6 +551,18 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
||||
int lengthInBytes,
|
||||
);
|
||||
|
||||
@Native<Void Function(Pointer<Void>, Int, Int, Int, Int, Float, Float)>(
|
||||
symbol: 'InternalFlutterGpu_RenderPass_SetViewport',
|
||||
)
|
||||
external void _setViewport(
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
double depthRangeZNear,
|
||||
double depthRangeZFar,
|
||||
);
|
||||
|
||||
@Native<
|
||||
Bool Function(
|
||||
Pointer<Void>,
|
||||
|
@ -218,6 +218,10 @@ bool RenderPass::Draw() {
|
||||
|
||||
render_pass_->SetStencilReference(stencil_reference);
|
||||
|
||||
if (viewport.has_value()) {
|
||||
render_pass_->SetViewport(viewport.value());
|
||||
}
|
||||
|
||||
if (scissor.has_value()) {
|
||||
render_pass_->SetScissor(scissor.value());
|
||||
}
|
||||
@ -559,6 +563,27 @@ void InternalFlutterGpu_RenderPass_SetScissor(flutter::gpu::RenderPass* wrapper,
|
||||
wrapper->scissor = impeller::TRect<int64_t>::MakeXYWH(x, y, width, height);
|
||||
}
|
||||
|
||||
void InternalFlutterGpu_RenderPass_SetViewport(
|
||||
flutter::gpu::RenderPass* wrapper,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
float z_near,
|
||||
float z_far) {
|
||||
auto rect = impeller::TRect<float>::MakeXYWH(x, y, width, height);
|
||||
|
||||
auto depth_range = impeller::DepthRange();
|
||||
depth_range.z_near = z_near;
|
||||
depth_range.z_far = z_far;
|
||||
|
||||
auto viewport = impeller::Viewport();
|
||||
viewport.rect = rect;
|
||||
viewport.depth_range = depth_range;
|
||||
|
||||
wrapper->viewport = viewport;
|
||||
}
|
||||
|
||||
void InternalFlutterGpu_RenderPass_SetStencilConfig(
|
||||
flutter::gpu::RenderPass* wrapper,
|
||||
int stencil_compare_operation,
|
||||
|
@ -81,6 +81,7 @@ class RenderPass : public RefCountedDartWrappable<RenderPass> {
|
||||
|
||||
uint32_t stencil_reference = 0;
|
||||
std::optional<impeller::TRect<int64_t>> scissor;
|
||||
std::optional<impeller::Viewport> viewport;
|
||||
|
||||
// Helper flag to determine whether the vertex_count should override the
|
||||
// element count. The index count takes precedent.
|
||||
@ -249,6 +250,16 @@ extern void InternalFlutterGpu_RenderPass_SetScissor(
|
||||
int width,
|
||||
int height);
|
||||
|
||||
FLUTTER_GPU_EXPORT
|
||||
extern void InternalFlutterGpu_RenderPass_SetViewport(
|
||||
flutter::gpu::RenderPass* wrapper,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
float z_near,
|
||||
float z_far);
|
||||
|
||||
FLUTTER_GPU_EXPORT
|
||||
extern void InternalFlutterGpu_RenderPass_SetCullMode(
|
||||
flutter::gpu::RenderPass* wrapper,
|
||||
|
@ -810,4 +810,71 @@ void main() async {
|
||||
expect(e.toString(), contains('Invalid values for scissor. All values should be positive.'));
|
||||
}
|
||||
}, skip: !impellerEnabled);
|
||||
|
||||
test('RenderPass.setViewport doesnt throw for valid values', () async {
|
||||
final state = createSimpleRenderPass();
|
||||
|
||||
state.renderPass.setViewport(gpu.Viewport(x: 25, width: 50, height: 100));
|
||||
state.renderPass.setViewport(gpu.Viewport(width: 50, height: 100));
|
||||
}, skip: !impellerEnabled);
|
||||
|
||||
test('RenderPass.setViewport throws for invalid values', () async {
|
||||
final state = createSimpleRenderPass();
|
||||
|
||||
try {
|
||||
state.renderPass.setViewport(gpu.Viewport(x: -1, width: 50, height: 100));
|
||||
fail('Exception not thrown for invalid viewport.');
|
||||
} catch (e) {
|
||||
expect(e.toString(), contains('Invalid values for viewport. All values should be positive.'));
|
||||
}
|
||||
|
||||
try {
|
||||
state.renderPass.setViewport(gpu.Viewport(width: 50, height: -100));
|
||||
fail('Exception not thrown for invalid viewport.');
|
||||
} catch (e) {
|
||||
expect(e.toString(), contains('Invalid values for viewport. All values should be positive.'));
|
||||
}
|
||||
}, skip: !impellerEnabled);
|
||||
|
||||
// Renders the middle part triangle using viewport.
|
||||
test('Can render portion of the triangle using viewport', () 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 viewport.
|
||||
state.renderPass.setViewport(gpu.Viewport(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_viewport.png');
|
||||
}, skip: !impellerEnabled);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user