未验证 提交 74d40c10 编写于 作者: C Chris Yang 提交者: GitHub

PlatformViewsController: clear composition_order_ in the beginning of each frame. (#22574)

上级 139fc641
...@@ -241,13 +241,13 @@ void FlutterPlatformViewsController::RegisterViewFactory( ...@@ -241,13 +241,13 @@ void FlutterPlatformViewsController::RegisterViewFactory(
gesture_recognizers_blocking_policies[idString] = gestureRecognizerBlockingPolicy; gesture_recognizers_blocking_policies[idString] = gestureRecognizerBlockingPolicy;
} }
void FlutterPlatformViewsController::SetFrameSize(SkISize frame_size) { void FlutterPlatformViewsController::BeginFrame(SkISize frame_size) {
ResetFrameState();
frame_size_ = frame_size; frame_size_ = frame_size;
} }
void FlutterPlatformViewsController::CancelFrame() { void FlutterPlatformViewsController::CancelFrame() {
picture_recorders_.clear(); ResetFrameState();
composition_order_.clear();
} }
// TODO(cyanglaz): https://github.com/flutter/flutter/issues/56474 // TODO(cyanglaz): https://github.com/flutter/flutter/issues/56474
...@@ -603,13 +603,6 @@ void FlutterPlatformViewsController::BringLayersIntoView(LayersMap layer_map) { ...@@ -603,13 +603,6 @@ void FlutterPlatformViewsController::BringLayersIntoView(LayersMap layer_map) {
} }
} }
void FlutterPlatformViewsController::EndFrame(
bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
// Reset the composition order, so next frame starts empty.
composition_order_.clear();
}
std::shared_ptr<FlutterPlatformViewLayer> FlutterPlatformViewsController::GetLayer( std::shared_ptr<FlutterPlatformViewLayer> FlutterPlatformViewsController::GetLayer(
GrDirectContext* gr_context, GrDirectContext* gr_context,
std::shared_ptr<IOSContext> ios_context, std::shared_ptr<IOSContext> ios_context,
...@@ -705,6 +698,11 @@ void FlutterPlatformViewsController::CommitCATransactionIfNeeded() { ...@@ -705,6 +698,11 @@ void FlutterPlatformViewsController::CommitCATransactionIfNeeded() {
} }
} }
void FlutterPlatformViewsController::ResetFrameState() {
picture_recorders_.clear();
composition_order_.clear();
}
} // namespace flutter } // namespace flutter
// This recognizers delays touch events from being dispatched to the responder chain until it failed // This recognizers delays touch events from being dispatched to the responder chain until it failed
......
...@@ -204,8 +204,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -204,8 +204,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
result); result);
XCTAssertNotNil(gMockPlatformView); XCTAssertNotNil(gMockPlatformView);
flutterPlatformViewsController->Reset();
} }
- (void)testChildClippingViewHitTests { - (void)testChildClippingViewHitTests {
...@@ -281,7 +279,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -281,7 +279,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds CGRect platformViewRectInFlutterView = [gMockPlatformView convertRect:gMockPlatformView.bounds
toView:mockFlutterView]; toView:mockFlutterView];
XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300))); XCTAssertTrue(CGRectEqualToRect(platformViewRectInFlutterView, CGRectMake(100, 100, 300, 300)));
flutterPlatformViewsController->Reset();
} }
- (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView { - (void)testChildClippingViewShouldBeTheBoundingRectOfPlatformView {
...@@ -351,8 +348,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -351,8 +348,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
XCTAssertLessThan( XCTAssertLessThan(
fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height), fabs(platformViewRectInFlutterView.size.height - childClippingView.frame.size.height),
kFloatCompareEpsilon); kFloatCompareEpsilon);
flutterPlatformViewsController->Reset();
} }
- (void)testClipRect { - (void)testClipRect {
...@@ -424,7 +419,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -424,7 +419,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
} }
} }
} }
flutterPlatformViewsController->Reset();
} }
- (void)testClipRRect { - (void)testClipRRect {
...@@ -496,7 +490,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -496,7 +490,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
} }
} }
} }
flutterPlatformViewsController->Reset();
} }
- (void)testClipPath { - (void)testClipPath {
...@@ -569,7 +562,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -569,7 +562,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
} }
} }
} }
flutterPlatformViewsController->Reset();
} }
- (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents { - (void)testSetFlutterViewControllerAfterCreateCanStillDispatchTouchEvents {
...@@ -632,8 +624,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -632,8 +624,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
flutterPlatformViewsController->SetFlutterViewController(mockFlutterViewContoller); flutterPlatformViewsController->SetFlutterViewController(mockFlutterViewContoller);
[forwardGectureRecognizer touchesBegan:touches2 withEvent:event2]; [forwardGectureRecognizer touchesBegan:touches2 withEvent:event2];
OCMVerify([mockFlutterViewContoller touchesBegan:touches2 withEvent:event2]); OCMVerify([mockFlutterViewContoller touchesBegan:touches2 withEvent:event2]);
flutterPlatformViewsController->Reset();
} }
- (void)testSetFlutterViewControllerInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled { - (void)testSetFlutterViewControllerInTheMiddleOfTouchEventShouldStillAllowGesturesToBeHandled {
...@@ -884,8 +874,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -884,8 +874,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
gpu_is_disabled->SetSwitch(false); gpu_is_disabled->SetSwitch(false);
XCTAssertTrue(flutterPlatformViewsController->SubmitFrame( XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(
nullptr, nullptr, std::move(mock_surface_submit_false), gpu_is_disabled)); nullptr, nullptr, std::move(mock_surface_submit_false), gpu_is_disabled));
flutterPlatformViewsController->Reset();
} }
- (void) - (void)
...@@ -937,6 +925,59 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) { ...@@ -937,6 +925,59 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
XCTAssertNil(gMockPlatformView); XCTAssertNil(gMockPlatformView);
} }
- (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder {
flutter::FlutterPlatformViewsTestMockPlatformViewDelegate mock_delegate;
auto thread_task_runner = CreateNewThread("FlutterPlatformViewsTest");
flutter::TaskRunners runners(/*label=*/self.name.UTF8String,
/*platform=*/thread_task_runner,
/*raster=*/thread_task_runner,
/*ui=*/thread_task_runner,
/*io=*/thread_task_runner);
auto flutterPlatformViewsController = std::make_shared<flutter::FlutterPlatformViewsController>();
auto platform_view = std::make_unique<flutter::PlatformViewIOS>(
/*delegate=*/mock_delegate,
/*rendering_api=*/flutter::IOSRenderingAPI::kSoftware,
/*platform_views_controller=*/flutterPlatformViewsController,
/*task_runners=*/runners);
UIView* mockFlutterView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)] autorelease];
flutterPlatformViewsController->SetFlutterView(mockFlutterView);
FlutterPlatformViewsTestMockFlutterPlatformFactory* factory =
[[FlutterPlatformViewsTestMockFlutterPlatformFactory new] autorelease];
flutterPlatformViewsController->RegisterViewFactory(
factory, @"MockFlutterPlatformView",
FlutterPlatformViewGestureRecognizersBlockingPolicyEager);
FlutterResult result = ^(id result) {
};
flutterPlatformViewsController->OnMethodCall(
[FlutterMethodCall
methodCallWithMethodName:@"create"
arguments:@{@"id" : @0, @"viewType" : @"MockFlutterPlatformView"}],
result);
// First frame, |GetCurrentCanvases| is not empty after composite.
flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300));
flutter::MutatorsStack stack;
SkMatrix finalMatrix;
auto embeddedViewParams1 =
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1));
flutterPlatformViewsController->CompositeEmbeddedView(0);
XCTAssertEqual(flutterPlatformViewsController->GetCurrentCanvases().size(), 1UL);
// Second frame, |GetCurrentCanvases| should be empty at the start
flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300));
XCTAssertTrue(flutterPlatformViewsController->GetCurrentCanvases().empty());
auto embeddedViewParams2 =
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams2));
flutterPlatformViewsController->CompositeEmbeddedView(0);
XCTAssertEqual(flutterPlatformViewsController->GetCurrentCanvases().size(), 1UL);
}
- (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view { - (int)alphaOfPoint:(CGPoint)point onView:(UIView*)view {
unsigned char pixel[4] = {0}; unsigned char pixel[4] = {0};
......
...@@ -141,7 +141,8 @@ class FlutterPlatformViewsController { ...@@ -141,7 +141,8 @@ class FlutterPlatformViewsController {
NSString* factoryId, NSString* factoryId,
FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy); FlutterPlatformViewGestureRecognizersBlockingPolicy gestureRecognizerBlockingPolicy);
void SetFrameSize(SkISize frame_size); // Called at the begining of each frame.
void BeginFrame(SkISize frame_size);
// Indicates that we don't compisite any platform views or overlays during this frame. // Indicates that we don't compisite any platform views or overlays during this frame.
// Also reverts the composition_order_ to its original state at the begining of the frame. // Also reverts the composition_order_ to its original state at the begining of the frame.
...@@ -175,12 +176,6 @@ class FlutterPlatformViewsController { ...@@ -175,12 +176,6 @@ class FlutterPlatformViewsController {
std::unique_ptr<SurfaceFrame> frame, std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch); const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch);
// Invoked at the very end of a frame.
// After invoking this method, nothing should happen on the current TaskRunner during the same
// frame.
void EndFrame(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger);
void OnMethodCall(FlutterMethodCall* call, FlutterResult& result); void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);
private: private:
...@@ -309,6 +304,9 @@ class FlutterPlatformViewsController { ...@@ -309,6 +304,9 @@ class FlutterPlatformViewsController {
std::shared_ptr<IOSContext> ios_context, std::shared_ptr<IOSContext> ios_context,
std::unique_ptr<SurfaceFrame> frame); std::unique_ptr<SurfaceFrame> frame);
// Resets the state of the frame.
void ResetFrameState();
FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController); FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController);
}; };
......
...@@ -37,7 +37,7 @@ void IOSExternalViewEmbedder::BeginFrame( ...@@ -37,7 +37,7 @@ void IOSExternalViewEmbedder::BeginFrame(
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) { fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::BeginFrame"); TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::BeginFrame");
FML_CHECK(platform_views_controller_); FML_CHECK(platform_views_controller_);
platform_views_controller_->SetFrameSize(frame_size); platform_views_controller_->BeginFrame(frame_size);
} }
// |ExternalViewEmbedder| // |ExternalViewEmbedder|
...@@ -88,7 +88,6 @@ void IOSExternalViewEmbedder::EndFrame(bool should_resubmit_frame, ...@@ -88,7 +88,6 @@ void IOSExternalViewEmbedder::EndFrame(bool should_resubmit_frame,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) { fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::EndFrame"); TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::EndFrame");
FML_CHECK(platform_views_controller_); FML_CHECK(platform_views_controller_);
return platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger);
} }
// |ExternalViewEmbedder| // |ExternalViewEmbedder|
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
6816DBAD2318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */; }; 6816DBAD2318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */; };
6816DBAE2318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */; }; 6816DBAE2318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */; };
68A5B63423EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */; }; 68A5B63423EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */; };
68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68D4017C2564859300ECD91A /* ContinuousTexture.m */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
...@@ -172,6 +173,8 @@ ...@@ -172,6 +173,8 @@
6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_iPhone SE_simulator.png"; sourceTree = "<group>"; }; 6816DBA82318696600A51400 /* golden_platform_view_cliprect_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_iPhone SE_simulator.png"; sourceTree = "<group>"; };
6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_iPhone SE_simulator.png"; sourceTree = "<group>"; }; 6816DBA92318696600A51400 /* golden_platform_view_cliprrect_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprrect_iPhone SE_simulator.png"; sourceTree = "<group>"; };
68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformViewGestureRecognizerTests.m; sourceTree = "<group>"; }; 68A5B63323EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlatformViewGestureRecognizerTests.m; sourceTree = "<group>"; };
68D4017B2564859300ECD91A /* ContinuousTexture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContinuousTexture.h; sourceTree = "<group>"; };
68D4017C2564859300ECD91A /* ContinuousTexture.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ContinuousTexture.m; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
...@@ -238,6 +241,8 @@ ...@@ -238,6 +241,8 @@
0A57B3BC2323C4BD00DD9521 /* ScreenBeforeFlutter.m */, 0A57B3BC2323C4BD00DD9521 /* ScreenBeforeFlutter.m */,
0A57B3BE2323C74200DD9521 /* FlutterEngine+ScenariosTest.m */, 0A57B3BE2323C74200DD9521 /* FlutterEngine+ScenariosTest.m */,
0A57B3C02323C74D00DD9521 /* FlutterEngine+ScenariosTest.h */, 0A57B3C02323C74D00DD9521 /* FlutterEngine+ScenariosTest.h */,
68D4017B2564859300ECD91A /* ContinuousTexture.h */,
68D4017C2564859300ECD91A /* ContinuousTexture.m */,
); );
path = Scenarios; path = Scenarios;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -462,6 +467,7 @@ ...@@ -462,6 +467,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
248D76DA22E388380012F0C1 /* main.m in Sources */, 248D76DA22E388380012F0C1 /* main.m in Sources */,
68D4017D2564859300ECD91A /* ContinuousTexture.m in Sources */,
24F1FB89230B4579005ACE7C /* TextPlatformView.m in Sources */, 24F1FB89230B4579005ACE7C /* TextPlatformView.m in Sources */,
248D76CC22E388370012F0C1 /* AppDelegate.m in Sources */, 248D76CC22E388370012F0C1 /* AppDelegate.m in Sources */,
0A57B3BF2323C74200DD9521 /* FlutterEngine+ScenariosTest.m in Sources */, 0A57B3BF2323C74200DD9521 /* FlutterEngine+ScenariosTest.m in Sources */,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#import "AppDelegate.h" #import "AppDelegate.h"
#import "ContinuousTexture.h"
#import "FlutterEngine+ScenariosTest.h" #import "FlutterEngine+ScenariosTest.h"
#import "ScreenBeforeFlutter.h" #import "ScreenBeforeFlutter.h"
#import "TextPlatformView.h" #import "TextPlatformView.h"
...@@ -52,6 +53,7 @@ ...@@ -52,6 +53,7 @@
@"--tap-status-bar" : @"tap_status_bar", @"--tap-status-bar" : @"tap_status_bar",
@"--text-semantics-focus" : @"text_semantics_focus", @"--text-semantics-focus" : @"text_semantics_focus",
@"--animated-color-square" : @"animated_color_square", @"--animated-color-square" : @"animated_color_square",
@"--platform-view-with-continuous-texture" : @"platform_view_with_continuous_texture"
}; };
__block NSString* flutterViewControllerTestName = nil; __block NSString* flutterViewControllerTestName = nil;
[launchArgsMap [launchArgsMap
...@@ -70,6 +72,10 @@ ...@@ -70,6 +72,10 @@
} }
[self.window makeKeyAndVisible]; [self.window makeKeyAndVisible];
if ([[[NSProcessInfo processInfo] arguments] containsObject:@"--with-continuous-texture"]) {
[ContinuousTexture
registerWithRegistrar:[self registrarForPlugin:@"com.constant.firing.texture"]];
}
return [super application:application didFinishLaunchingWithOptions:launchOptions]; return [super application:application didFinishLaunchingWithOptions:launchOptions];
} }
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Flutter/Flutter.h>
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
// A texture plugin that ready textures continuously.
@interface ContinuousTexture : NSObject <FlutterPlugin>
@end
// The testing texture used by |ContinuousTexture|
@interface FlutterScenarioTestTexture : NSObject <FlutterTexture>
@end
NS_ASSUME_NONNULL_END
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ContinuousTexture.h"
@implementation ContinuousTexture
+ (void)registerWithRegistrar:(nonnull NSObject<FlutterPluginRegistrar>*)registrar {
NSObject<FlutterTextureRegistry>* textureRegistry = [registrar textures];
FlutterScenarioTestTexture* texture = [[FlutterScenarioTestTexture alloc] init];
int64_t textureId = [textureRegistry registerTexture:texture];
[NSTimer scheduledTimerWithTimeInterval:0.05
repeats:YES
block:^(NSTimer* _Nonnull timer) {
[textureRegistry textureFrameAvailable:textureId];
}];
}
@end
@implementation FlutterScenarioTestTexture
- (CVPixelBufferRef _Nullable)copyPixelBuffer {
return [self pixelBuffer];
}
- (CVPixelBufferRef)pixelBuffer {
NSDictionary* options = @{
// This key is required to generate SKPicture with CVPixelBufferRef in metal.
(NSString*)kCVPixelBufferMetalCompatibilityKey : @YES
};
CVPixelBufferRef pxbuffer = NULL;
CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, 200, 200, kCVPixelFormatType_32BGRA,
(__bridge CFDictionaryRef)options, &pxbuffer);
NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);
CVPixelBufferLockBaseAddress(pxbuffer, 0);
return pxbuffer;
}
@end
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#import "GoldenPlatformViewTests.h" #import "GoldenPlatformViewTests.h"
static const NSInteger kSecondsToWaitForPlatformView = 30;
@interface PlatformViewUITests : GoldenPlatformViewTests @interface PlatformViewUITests : GoldenPlatformViewTests
@end @end
...@@ -170,4 +172,35 @@ ...@@ -170,4 +172,35 @@
XCUIDevice.sharedDevice.orientation = UIDeviceOrientationLandscapeLeft; XCUIDevice.sharedDevice.orientation = UIDeviceOrientationLandscapeLeft;
[self checkGolden]; [self checkGolden];
} }
@end
@interface PlatformViewWithContinuousTexture : XCTestCase
@end
@implementation PlatformViewWithContinuousTexture
- (void)setUp {
self.continueAfterFailure = NO;
}
- (void)testPlatformViewWithContinuousTexture {
XCUIApplication* app = [[XCUIApplication alloc] init];
app.launchArguments =
@[ @"--platform-view-with-continuous-texture", @"--with-continuous-texture" ];
[app launch];
XCUIElement* platformView = app.textViews.firstMatch;
BOOL exists = [platformView waitForExistenceWithTimeout:kSecondsToWaitForPlatformView];
if (!exists) {
XCTFail(@"It took longer than %@ second to find the platform view."
@"There might be issues with the platform view's construction,"
@"or with how the scenario is built.",
@(kSecondsToWaitForPlatformView));
}
XCTAssertNotNil(platformView);
}
@end @end
...@@ -579,6 +579,23 @@ class PlatformViewForTouchIOSScenario extends Scenario ...@@ -579,6 +579,23 @@ class PlatformViewForTouchIOSScenario extends Scenario
} }
} }
/// A simple platform view for testing platform view with a continuous texture layer.
/// For example, it simulates a video being played.
class PlatformViewWithContinuousTexture extends PlatformViewScenario {
/// Constructs a platform view with continuous texture layer.
PlatformViewWithContinuousTexture(PlatformDispatcher dispatcher, String text, { int id = 0 })
: super(dispatcher, text, id: id);
@override
void onBeginFrame(Duration duration) {
final SceneBuilder builder = SceneBuilder();
builder.addTexture(0, width: 300, height: 300, offset: const Offset(200, 200));
finishBuilderByAddingPlatformViewAndPicture(builder, id);
}
}
mixin _BasePlatformViewScenarioMixin on Scenario { mixin _BasePlatformViewScenarioMixin on Scenario {
int _textureId; int _textureId;
......
...@@ -43,6 +43,7 @@ Map<String, ScenarioFactory> _scenarios = <String, ScenarioFactory>{ ...@@ -43,6 +43,7 @@ Map<String, ScenarioFactory> _scenarios = <String, ScenarioFactory>{
'tap_status_bar': () => TouchesScenario(PlatformDispatcher.instance), 'tap_status_bar': () => TouchesScenario(PlatformDispatcher.instance),
'text_semantics_focus': () => SendTextFocusSemantics(PlatformDispatcher.instance), 'text_semantics_focus': () => SendTextFocusSemantics(PlatformDispatcher.instance),
'initial_route_reply': () => InitialRouteReply(PlatformDispatcher.instance), 'initial_route_reply': () => InitialRouteReply(PlatformDispatcher.instance),
'platform_view_with_continuous_texture': () => PlatformViewWithContinuousTexture(PlatformDispatcher.instance, 'Platform View', id: _viewId++),
}; };
Map<String, dynamic> _currentScenarioParams = <String, dynamic>{}; Map<String, dynamic> _currentScenarioParams = <String, dynamic>{};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册