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 {
|
base class RenderTarget {
|
||||||
const RenderTarget({
|
const RenderTarget({
|
||||||
this.colorAttachments = const <ColorAttachment>[],
|
this.colorAttachments = const <ColorAttachment>[],
|
||||||
@ -346,6 +374,21 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
|||||||
_setDepthWriteEnable(enable);
|
_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) {
|
void setDepthCompareOperation(CompareFunction compareFunction) {
|
||||||
_setDepthCompareOperation(compareFunction.index);
|
_setDepthCompareOperation(compareFunction.index);
|
||||||
}
|
}
|
||||||
@ -508,6 +551,18 @@ base class RenderPass extends NativeFieldWrapperClass1 {
|
|||||||
int lengthInBytes,
|
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<
|
@Native<
|
||||||
Bool Function(
|
Bool Function(
|
||||||
Pointer<Void>,
|
Pointer<Void>,
|
||||||
|
@ -218,6 +218,10 @@ bool RenderPass::Draw() {
|
|||||||
|
|
||||||
render_pass_->SetStencilReference(stencil_reference);
|
render_pass_->SetStencilReference(stencil_reference);
|
||||||
|
|
||||||
|
if (viewport.has_value()) {
|
||||||
|
render_pass_->SetViewport(viewport.value());
|
||||||
|
}
|
||||||
|
|
||||||
if (scissor.has_value()) {
|
if (scissor.has_value()) {
|
||||||
render_pass_->SetScissor(scissor.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);
|
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(
|
void InternalFlutterGpu_RenderPass_SetStencilConfig(
|
||||||
flutter::gpu::RenderPass* wrapper,
|
flutter::gpu::RenderPass* wrapper,
|
||||||
int stencil_compare_operation,
|
int stencil_compare_operation,
|
||||||
|
@ -81,6 +81,7 @@ class RenderPass : public RefCountedDartWrappable<RenderPass> {
|
|||||||
|
|
||||||
uint32_t stencil_reference = 0;
|
uint32_t stencil_reference = 0;
|
||||||
std::optional<impeller::TRect<int64_t>> scissor;
|
std::optional<impeller::TRect<int64_t>> scissor;
|
||||||
|
std::optional<impeller::Viewport> viewport;
|
||||||
|
|
||||||
// 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.
|
||||||
@ -249,6 +250,16 @@ extern void InternalFlutterGpu_RenderPass_SetScissor(
|
|||||||
int width,
|
int width,
|
||||||
int height);
|
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
|
FLUTTER_GPU_EXPORT
|
||||||
extern void InternalFlutterGpu_RenderPass_SetCullMode(
|
extern void InternalFlutterGpu_RenderPass_SetCullMode(
|
||||||
flutter::gpu::RenderPass* wrapper,
|
flutter::gpu::RenderPass* wrapper,
|
||||||
|
@ -810,4 +810,71 @@ void main() async {
|
|||||||
expect(e.toString(), contains('Invalid values for scissor. All values should be positive.'));
|
expect(e.toString(), contains('Invalid values for scissor. All values should be positive.'));
|
||||||
}
|
}
|
||||||
}, skip: !impellerEnabled);
|
}, 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