Hash :
b380ed1f
Author :
Date :
2024-02-14T09:31:26
Vulkan: Add EGL_ANGLE_global_fence_sync Chrome has an implicit assumption that due to context virtualization, signaling a fence in one context results in synchronization with _all_ contexts that have previously made submissions. This is not per EGL spec, but the functionality is easily implementable in the Vulkan backend. In the Vulkan backend, each context is given its own "timeline" of submissions (tracked by serials associated with "indices"). The required functionality is implemented through a new EGL fence sync object whose sole difference is that it synchronizes with all the existing timelines rather than the one of the current context. Bug: b/318721705 Change-Id: I6c45d065e592d0d4ed627ce9695196b1086d5021 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5297396 Reviewed-by: Charlie Lao <cclao@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
//
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// EGLSync.cpp: Implements the egl::Sync class.
#include "libANGLE/EGLSync.h"
#include "angle_gl.h"
#include "common/utilities.h"
#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/renderer/EGLReusableSync.h"
#include "libANGLE/renderer/EGLSyncImpl.h"
namespace egl
{
Sync::Sync(rx::EGLImplFactory *factory, EGLenum type)
: mLabel(nullptr), mId({0}), mType(type), mCondition(0), mNativeFenceFD(0)
{
switch (mType)
{
case EGL_SYNC_FENCE:
case EGL_SYNC_GLOBAL_FENCE_ANGLE:
case EGL_SYNC_NATIVE_FENCE_ANDROID:
case EGL_SYNC_METAL_SHARED_EVENT_ANGLE:
mFence = std::unique_ptr<rx::EGLSyncImpl>(factory->createSync());
break;
case EGL_SYNC_REUSABLE_KHR:
mFence = std::unique_ptr<rx::EGLSyncImpl>(new rx::ReusableSync());
break;
default:
UNREACHABLE();
}
}
void Sync::onDestroy(const Display *display)
{
ASSERT(mFence);
mFence->onDestroy(display);
}
Sync::~Sync() {}
Error Sync::initialize(const Display *display,
const gl::Context *context,
const SyncID &id,
const AttributeMap &attribs)
{
mId = id;
mAttributeMap = attribs;
mNativeFenceFD =
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID);
mCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
// Per extension spec: Signaling Condition.
// "If the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute is not
// EGL_NO_NATIVE_FENCE_FD_ANDROID then the EGL_SYNC_CONDITION_KHR attribute
// is set to EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID and the EGL_SYNC_STATUS_KHR
// attribute is set to reflect the signal status of the native fence object.
if ((mType == EGL_SYNC_NATIVE_FENCE_ANDROID) &&
(mNativeFenceFD != EGL_NO_NATIVE_FENCE_FD_ANDROID))
{
mCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
}
// Per extension spec: Signaling Condition.
if (mType == EGL_SYNC_METAL_SHARED_EVENT_ANGLE)
{
mCondition = attribs.getAsInt(EGL_SYNC_CONDITION, EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR);
}
return mFence->initialize(display, context, mType, mAttributeMap);
}
void Sync::setLabel(EGLLabelKHR label)
{
mLabel = label;
}
EGLLabelKHR Sync::getLabel() const
{
return mLabel;
}
Error Sync::clientWait(const Display *display,
const gl::Context *context,
EGLint flags,
EGLTime timeout,
EGLint *outResult)
{
return mFence->clientWait(display, context, flags, timeout, outResult);
}
Error Sync::serverWait(const Display *display, const gl::Context *context, EGLint flags)
{
return mFence->serverWait(display, context, flags);
}
Error Sync::signal(const Display *display, const gl::Context *context, EGLint mode)
{
return mFence->signal(display, context, mode);
}
Error Sync::getStatus(const Display *display, EGLint *outStatus) const
{
return mFence->getStatus(display, outStatus);
}
Error Sync::copyMetalSharedEventANGLE(const Display *display, void **result) const
{
return mFence->copyMetalSharedEventANGLE(display, result);
}
Error Sync::dupNativeFenceFD(const Display *display, EGLint *result) const
{
return mFence->dupNativeFenceFD(display, result);
}
} // namespace egl