Hash :
d4083c79
Author :
Date :
2025-01-31T15:06:36
Metal: Make ObjCPtr available to all modules Move ObjCPtr implementation to src/common/ObjCPtr.h, angle::ObjCPtr so that it's available also outside libANGLE. Bug: angleproject:393263506 Change-Id: I8ecd5632c7ae33ef4b409fc820fad229e91bc0ab Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6219318 Auto-Submit: Kimmo Kinnunen <kkinnunen@apple.com> Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Kimmo Kinnunen <kkinnunen@apple.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
//
// Copyright 2025 The ANGLE Project Authors. All rights reserved.
// of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ObjCPtr_test.cpp:
// Test for functionality in ObjCPtr.h
#import "common/apple/ObjCPtr.h"
#import <Metal/Metal.h>
#import "gtest/gtest.h"
namespace
{
using namespace angle;
// This explains why the implementation has ObjCPtr<U> &&other constructor/operator=
// as opposed to ObjCPtr &&other ones.
TEST(ObjCPtrTest, ImplementationDetailExplanation)
{
// For Obj-C interfaces we would like the client to use ObjCPtr<T> form, similar
// to any C++ smart pointer.
MTLStencilDescriptor *rawDesc = nil;
ObjCPtr<MTLStencilDescriptor> stencilDesc = adoptObjCPtr(rawDesc);
// For Obj-C protocols we would like the client to use ObjCPtr<id<P>> form,
// which resembles the normal smart pointer form textually:
id<MTLDevice> rawDevice = nil;
ObjCPtr<id<MTLDevice>> device = adoptObjCPtr(rawDevice);
// adoptObjCPtr for Obj-C interface types works as expected:
{
auto result = adoptObjCPtr(rawDesc);
static_assert(std::is_same_v<ObjCPtr<MTLStencilDescriptor>, decltype(result)>);
}
// adoptObjCPtr for protocols does not:
{
auto result = adoptObjCPtr(rawDevice);
static_assert(!std::is_same_v<ObjCPtr<id<MTLDevice>>, decltype(result)>);
static_assert(
std::is_same_v<ObjCPtr<std::remove_pointer_t<id<MTLDevice>>>, decltype(result)>);
}
}
TEST(ObjCPtrTest, Comparison)
{
ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
ObjCPtr<MTLStencilDescriptor> b;
EXPECT_TRUE(a == a);
EXPECT_TRUE(a != b);
EXPECT_TRUE(a != nullptr);
EXPECT_TRUE(b == nullptr);
EXPECT_TRUE(nullptr != a);
EXPECT_TRUE(nullptr == b);
EXPECT_TRUE(a != nil);
EXPECT_TRUE(b == nil);
EXPECT_TRUE(nil != a);
EXPECT_TRUE(nil == b);
EXPECT_TRUE(!!a);
EXPECT_TRUE(!b);
}
TEST(ObjCPtrTest, Copy)
{
ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
ObjCPtr<MTLStencilDescriptor> b = a;
EXPECT_EQ(a, b);
EXPECT_NE(a, nullptr);
a = {};
EXPECT_NE(a, b);
}
TEST(ObjCPtrTest, LeakObject)
{
ObjCPtr<MTLStencilDescriptor> a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
EXPECT_NE(a, nullptr);
auto rawA = a.leakObject();
EXPECT_EQ(a, nullptr);
EXPECT_EQ(a.leakObject(), nullptr);
a = adoptObjCPtr(rawA);
}
TEST(ObjCPtrTest, SelfAssignment)
{
ObjCPtr a = adoptObjCPtr([[MTLStencilDescriptor alloc] init]);
auto rawA = a.get();
auto &r = a;
a = r;
EXPECT_EQ(a, rawA);
a = std::move(r);
EXPECT_EQ(a, rawA);
}
} // namespace