forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Setup a Metal test surface and add a new unit-test target that tests …
…the testing utilities. `//flutter/testing` now contains a lot of utilities used by other test targets. This includes stuff like working with render targets that use either OpenGL or Metal, fixtures for interacting with the Dart VM, test assertion predicates, etc.. However, these utilities themselves are not tested as part of a standalone test suite. Instead, only the test targets that include it exercise these utilities. Since these are no longer trivial, a new test target has been added that tests the testing utilities directly.
- Loading branch information
1 parent
591144d
commit ed30d77
Showing
9 changed files
with
343 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/testing/test_metal_surface.h" | ||
|
||
#if TESTING_ENABLE_METAL | ||
#include "flutter/testing/test_metal_surface_impl.h" | ||
#endif // TESTING_ENABLE_METAL | ||
|
||
namespace flutter { | ||
|
||
bool TestMetalSurface::PlatformSupportsMetal() { | ||
#if TESTING_ENABLE_METAL | ||
return true; | ||
#else // TESTING_ENABLE_METAL | ||
return false; | ||
#endif // TESTING_ENABLE_METAL | ||
} | ||
|
||
std::unique_ptr<TestMetalSurface> TestMetalSurface::Create( | ||
SkISize surface_size) { | ||
#if TESTING_ENABLE_METAL | ||
return std::make_unique<TestMetalSurfaceImpl>(surface_size); | ||
#else // TESTING_ENABLE_METAL | ||
return nullptr; | ||
#endif // TESTING_ENABLE_METAL | ||
} | ||
|
||
TestMetalSurface::TestMetalSurface() = default; | ||
|
||
TestMetalSurface::~TestMetalSurface() = default; | ||
|
||
bool TestMetalSurface::IsValid() const { | ||
return impl_ ? impl_->IsValid() : false; | ||
} | ||
|
||
sk_sp<GrContext> TestMetalSurface::GetGrContext() const { | ||
return impl_ ? impl_->GetGrContext() : nullptr; | ||
} | ||
|
||
sk_sp<SkSurface> TestMetalSurface::GetSurface() const { | ||
return impl_ ? impl_->GetSurface() : nullptr; | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_TESTING_TEST_METAL_SURFACE_H_ | ||
#define FLUTTER_TESTING_TEST_METAL_SURFACE_H_ | ||
|
||
#include "flutter/fml/macros.h" | ||
#include "third_party/skia/include/core/SkSize.h" | ||
#include "third_party/skia/include/core/SkSurface.h" | ||
#include "third_party/skia/include/gpu/GrContext.h" | ||
|
||
namespace flutter { | ||
|
||
//------------------------------------------------------------------------------ | ||
/// @brief Creates a MTLTexture backed SkSurface and context that can be | ||
/// used to render to in unit-tests. | ||
/// | ||
class TestMetalSurface { | ||
public: | ||
static bool PlatformSupportsMetal(); | ||
|
||
static std::unique_ptr<TestMetalSurface> Create( | ||
SkISize surface_size = SkISize::MakeEmpty()); | ||
|
||
virtual ~TestMetalSurface(); | ||
|
||
virtual bool IsValid() const; | ||
|
||
virtual sk_sp<GrContext> GetGrContext() const; | ||
|
||
virtual sk_sp<SkSurface> GetSurface() const; | ||
|
||
protected: | ||
TestMetalSurface(); | ||
|
||
private: | ||
std::unique_ptr<TestMetalSurface> impl_; | ||
|
||
TestMetalSurface(std::unique_ptr<TestMetalSurface> impl); | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(TestMetalSurface); | ||
}; | ||
|
||
} // namespace flutter | ||
|
||
#endif // FLUTTER_TESTING_TEST_METAL_SURFACE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef FLUTTER_TESTING_TEST_METAL_SURFACE_IMPL_H_ | ||
#define FLUTTER_TESTING_TEST_METAL_SURFACE_IMPL_H_ | ||
|
||
#include "flutter/fml/macros.h" | ||
#include "flutter/testing/test_metal_surface.h" | ||
|
||
namespace flutter { | ||
|
||
class TestMetalSurfaceImpl : public TestMetalSurface { | ||
public: | ||
TestMetalSurfaceImpl(SkISize surface_size); | ||
|
||
// |TestMetalSurface| | ||
~TestMetalSurfaceImpl() override; | ||
|
||
private: | ||
bool is_valid_ = false; | ||
sk_sp<GrContext> context_; | ||
sk_sp<SkSurface> surface_; | ||
|
||
// |TestMetalSurface| | ||
bool IsValid() const override; | ||
|
||
// |TestMetalSurface| | ||
sk_sp<GrContext> GetGrContext() const override; | ||
|
||
// |TestMetalSurface| | ||
sk_sp<SkSurface> GetSurface() const override; | ||
|
||
FML_DISALLOW_COPY_AND_ASSIGN(TestMetalSurfaceImpl); | ||
}; | ||
|
||
} // namespace flutter | ||
|
||
#endif // FLUTTER_TESTING_TEST_METAL_SURFACE_IMPL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/testing/test_metal_surface_impl.h" | ||
|
||
#include <Metal/Metal.h> | ||
|
||
#include "flutter/fml/logging.h" | ||
#include "flutter/fml/platform/darwin/scoped_nsobject.h" | ||
#include "third_party/skia/include/core/SkSurface.h" | ||
|
||
namespace flutter { | ||
|
||
TestMetalSurfaceImpl::TestMetalSurfaceImpl(SkISize surface_size) { | ||
if (surface_size.isEmpty()) { | ||
FML_LOG(ERROR) << "Size of test Metal surface was empty."; | ||
return; | ||
} | ||
|
||
auto device = fml::scoped_nsobject{[MTLCreateSystemDefaultDevice() retain]}; | ||
if (!device) { | ||
FML_LOG(ERROR) << "Could not acquire Metal device."; | ||
return; | ||
} | ||
|
||
auto command_queue = fml::scoped_nsobject{[device.get() newCommandQueue]}; | ||
if (!command_queue) { | ||
FML_LOG(ERROR) << "Could not create the default command queue."; | ||
return; | ||
} | ||
|
||
auto texture_descriptor = fml::scoped_nsobject{[[MTLTextureDescriptor | ||
texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm | ||
width:surface_size.width() | ||
height:surface_size.height() | ||
mipmapped:NO] retain]}; | ||
|
||
// The most pessimistic option and disables all optimizations but allows tests | ||
// the most flexible access to the surface. They may read and wrote to the | ||
// surface from shaders or use as a pixel view. | ||
texture_descriptor.get().usage = MTLTextureUsageUnknown; | ||
|
||
if (!texture_descriptor) { | ||
FML_LOG(ERROR) << "Invalid texture descriptor."; | ||
return; | ||
} | ||
|
||
auto texture = fml::scoped_nsobject{ | ||
[device.get() newTextureWithDescriptor:texture_descriptor.get()]}; | ||
|
||
if (!texture) { | ||
FML_LOG(ERROR) << "Could not create texture from texture descriptor."; | ||
return; | ||
} | ||
|
||
auto skia_context = GrContext::MakeMetal(device.get(), command_queue.get()); | ||
|
||
if (skia_context) { | ||
// Skia wants ownership of the device and queue. If a context was created, | ||
// we now no longer own the argument. Release the arguments only on | ||
// successful creation of the context. | ||
FML_ALLOW_UNUSED_LOCAL(device.release()); | ||
FML_ALLOW_UNUSED_LOCAL(command_queue.release()); | ||
} else { | ||
FML_LOG(ERROR) << "Could not create the GrContext from the Metal Device " | ||
"and command queue."; | ||
return; | ||
} | ||
|
||
GrMtlTextureInfo skia_texture_info; | ||
skia_texture_info.fTexture = sk_cf_obj<const void*>{[texture.get() retain]}; | ||
|
||
auto backend_render_target = GrBackendRenderTarget{ | ||
surface_size.width(), // width | ||
surface_size.height(), // height | ||
1, // sample count | ||
skia_texture_info // texture info | ||
}; | ||
|
||
auto surface = SkSurface::MakeFromBackendRenderTarget( | ||
skia_context.get(), // context | ||
backend_render_target, // backend render target | ||
kTopLeft_GrSurfaceOrigin, // surface origin | ||
kBGRA_8888_SkColorType, // color type | ||
nullptr, // color space | ||
nullptr, // surface properties | ||
nullptr, // release proc (texture is already ref counted in sk_cf_obj) | ||
nullptr // release context | ||
); | ||
|
||
if (!surface) { | ||
FML_LOG(ERROR) << "Could not create Skia surface from a Metal texture."; | ||
return; | ||
} | ||
|
||
surface_ = std::move(surface); | ||
context_ = std::move(skia_context); | ||
|
||
is_valid_ = true; | ||
} | ||
|
||
// |TestMetalSurface| | ||
TestMetalSurfaceImpl::~TestMetalSurfaceImpl() = default; | ||
|
||
// |TestMetalSurface| | ||
bool TestMetalSurfaceImpl::IsValid() const { | ||
return is_valid_; | ||
} | ||
// |TestMetalSurface| | ||
sk_sp<GrContext> TestMetalSurfaceImpl::GetGrContext() const { | ||
return IsValid() ? context_ : nullptr; | ||
} | ||
// |TestMetalSurface| | ||
sk_sp<SkSurface> TestMetalSurfaceImpl::GetSurface() const { | ||
return IsValid() ? surface_ : nullptr; | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright 2013 The Flutter Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "flutter/testing/test_metal_surface.h" | ||
#include "flutter/testing/testing.h" | ||
|
||
namespace flutter { | ||
namespace testing { | ||
|
||
TEST(TestMetalSurface, EmptySurfaceIsInvalid) { | ||
if (!TestMetalSurface::PlatformSupportsMetal()) { | ||
GTEST_SKIP(); | ||
} | ||
|
||
auto surface = TestMetalSurface::Create(); | ||
ASSERT_NE(surface, nullptr); | ||
ASSERT_FALSE(surface->IsValid()); | ||
} | ||
|
||
TEST(TestMetalSurface, CanCreateValidTestMetalSurface) { | ||
if (!TestMetalSurface::PlatformSupportsMetal()) { | ||
GTEST_SKIP(); | ||
} | ||
|
||
auto surface = TestMetalSurface::Create(SkISize::Make(100, 100)); | ||
ASSERT_NE(surface, nullptr); | ||
ASSERT_TRUE(surface->IsValid()); | ||
ASSERT_NE(surface->GetSurface(), nullptr); | ||
ASSERT_NE(surface->GetGrContext(), nullptr); | ||
} | ||
|
||
} // namespace testing | ||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters