• Show log

    Commit

  • Hash : 36c3e0f5
    Author : Igor Nazarov
    Date : 2023-01-17T17:42:59

    Implement "Shared Context Mutex" functionality.
    
    Existing implementation uses single `GlobalMutex` for
    - EGL calls
    - GL calls for Contexts with concurrent access.
    
    This CL introduces abstract `egl::ContextMutex` with two
    implementations:
    - SingleContextMutex;
    - SharedContextMutex<Mutex>;
    
    Note:
    `std::mutex` is used in this commit. It is very easy to change mutex
    type either at compile-time or at run-time (single type per Display).
    
    When Context:
    - is not Shared;
    - does not use `EGLImage`s;
    - does not use EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE
    - does not use EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE
    then it will be using `SingleContextMutex` with minimal overhead.
    
    Before such Context is used as `shareContext` or uses `EGLImage`
    its mutex replaced by `SharedContextMutex<Mutex>`.
    
    The `GlobalMutex` is only used for EGL calls, while `egl::ContextMutex`
    implementations for GL calls. Because some EGL calls use Context,
    explicit `egl::ContextMutex` lock is required. This is implemented by
    generating "egl_context_mutex_autogen.h" header, and insertion of
    `ANGLE_EGL_SCOPED_CONTEXT_LOCK()` macro before `ANGLE_EGL_VALIDATE()`
    in each EGL entry point. Implementation in "egl_context_lock_impl.h"
    returns lock for required APIs. Special cases of `egl::ContextMutex`
    lock handled separately. `std::unique_lock<>` is not used for
    performance reasons.
    
    `egl::ContextMutex` explicitly locked when capturing EGL calls.
    
    Fixes EGLImage problem:
        https://chromium.googlesource.com/angle/angle/+/e18240d136d15e5cdfa4fa4a6355ca21c8d807b6
        Mark contexts as shared when importing EGL images.
    
    Details:
    - EGLImage inherits Context's mutex when created.
      Mutex is used when the EGLImage accessed or destroyed.
    - When EGLImage is used in Context with other `egl::ContextMutex`,
      two mutexes are merged into one.
    - After the mutex merge, Context Groups will remain separate,
      but will not be able to run in parallel.
    
    Fixes race when checking `context->isShared()` in the
    `SCOPED_SHARE_CONTEXT_LOCK()` macro. One Context may start executing GL
    call while not "Shared", but become "Shared" inside the call. New
    (second) "Shared" Context may immediately start using GL and potentially
    corrupt some "Shared" state.
    
    Possible performance benefit: allows parallel execution in some cases,
    when single `GlobalMutex` would block.
    
    Important note:
        Process of replacing the `SingleContextMutex` by
        `SharedContextMutex<Mutex>` is not 100% safe. This mean that
        original Context may still be using `SingleContextMutex` after
        activating `SharedContextMutex<Mutex>`. However, this was always
        the case before introduction of this CL. Old `Context::mShared`
        member update was not synchronized in any way at all. In other
        words, this solution does not 100% fix the original problem.
        For 100% safe solution `SingleContextMutex` should not be used
        (always pass `SharedContextMutex<Mutex>` to the `gl::Context`
        constructor). See `lockAndActivateSharedContextMutex()` for more
        details.
    
    CL adds new build option:
        angle_enable_shared_context_mutex = true
    
    Behavior with other build options:
    - When:
        `angle_enable_shared_context_mutex`    is disabled or
        `angle_enable_share_context_lock`      is disabled or
        `angle_force_context_check_every_call` is enabled,
      Contexts will always have `SingleContextMutex`, however it will be
      only used in special cases. `SCOPED_SHARE_CONTEXT_LOCK()` will use
      `GlobalMutex` when applicable.
    - Otherwise, `SCOPED_SHARE_CONTEXT_LOCK()` will use `egl::ContextMutex`.
    
    Some GFXBench "1080p Driver Overhead 2 Offscreen" performance numbers.
    Tested on S906B (Samsung Galaxy S22+) on old ANGLE base:
        https://chromium.googlesource.com/angle/angle/+/807c94ea85e046c6f279d081d99f0fb1bcf1191a
        Capture/Replay: Adjust tests do adhere to capture limits
    
    Each test result is an average frame number from 6 runs.
    
        SingleContextMutex                            6579 ( +0.13%)
        (old) GetContextLock() (mShared is false)     6570
    
    Forced `mShared = true` or NOT using `SingleContextMutex`.
    
        SharedContextMutex<std::mutex> FORCE          5061 (-22.97%)
        (old) GetContextLock() FORCE                  4766 (-27.46%)
    
    Bug: angleproject:6957
    Bug: chromium:1336126
    Change-Id: Idcd919f9d4bf482b9ae489bd8b4415ec96048e32
    Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4374545
    Reviewed-by: Geoff Lang <geofflang@chromium.org>
    Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
    Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
    

  • Properties

  • Git HTTP https://git.kmx.io/kc3-lang/angle.git
    Git SSH git@git.kmx.io:kc3-lang/angle.git
    Public access ? public
    Description

    A conformant OpenGL ES implementation for Windows, Mac, Linux, iOS and Android.

    Homepage

    Github

    Users
    thodg_m kc3_lang_org thodg_w www_kmx_io thodg thodg_l
    Tags