Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

383 Commits   1 Branch   1 Tag
Index: X11/libs/webkitgtk/2.40.1/Makefile
===================================================================
--- X11/libs/webkitgtk/2.40.1/Makefile	(revision 88)
+++ X11/libs/webkitgtk/2.40.1/Makefile	(revision 89)
@@ -63,6 +63,7 @@
 REQUIRES          += libs/libsoup3/3.4.2
 REQUIRES          += libs/libsecret/0.20.4
 REQUIRES          += libs/libseccomp/2.5.4
+REQUIRES          += app/sqlite/3.39.4.0
 REQUIRES          += X11/libs/gtk4/4.11.2
 REQUIRES          += X11/app/xdg-dbus-proxy/0.1.4
 REQUIRES          += X11/libs/libwpe/1.14.1
@@ -97,6 +98,11 @@
 install_target     = $(TARGET_BUILD_DIR)/.install_done
 
 
+ifneq ($(filter $(TOOLCHAIN),$(TOOLCHAIN_JZ47XX_GLIBC) $(TOOLCHAIN_P5600_GLIBC)),)
+OPT_PATCHES = PATCHES.mips
+endif
+
+
 ####### Targets
 
 PKG_GROUP = xlibs
@@ -363,6 +369,7 @@
 $(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
 	$(UNPACK_SRC_ARCHIVE)
 	$(APPLY_PATCHES)
+	$(call apply-opt-patches, $(SRC_DIR))
 	@echo "set(CMAKE_SYSTEM_NAME Linux)"             > $(toolchain-file)
 	@echo "set(CMAKE_SYSTEM_PROCESSOR $(cpu_arch))" >> $(toolchain-file)
 	@touch $@
Index: X11/libs/webkitgtk/2.40.1/PATCHES
===================================================================
--- X11/libs/webkitgtk/2.40.1/PATCHES	(revision 88)
+++ X11/libs/webkitgtk/2.40.1/PATCHES	(revision 89)
@@ -1,4 +1,6 @@
 
 ../../../../sources/packages/x/webkitgtk/patches/webkitgtk-2.40.1-arm-neon.patch     -p0
+../../../../sources/packages/x/webkitgtk/patches/webkitgtk-2.40.1-i386-sse.patch     -p0
+
 ../../../../sources/packages/x/webkitgtk/patches/webkitgtk-2.40.1-bwrap-cross.patch  -p0
 ../../../../sources/packages/x/webkitgtk/patches/webkitgtk-2.40.1-source-brush.patch -p0
Index: X11/libs/webkitgtk/2.40.1/PATCHES.mips
===================================================================
--- X11/libs/webkitgtk/2.40.1/PATCHES.mips	(nonexistent)
+++ X11/libs/webkitgtk/2.40.1/PATCHES.mips	(revision 89)
@@ -0,0 +1,2 @@
+
+../../../../sources/packages/x/webkitgtk/patches/webkitgtk-2.40.1-mips-atomic.patch  -p0
Index: sources/packages/x/webkitgtk/Makefile
===================================================================
--- sources/packages/x/webkitgtk/Makefile	(revision 88)
+++ sources/packages/x/webkitgtk/Makefile	(revision 89)
@@ -15,6 +15,8 @@
 sha1s       = $(addsuffix .sha1sum, $(tarballs))
 
 patches     = $(CURDIR)/patches/webkitgtk-2.40.1-arm-neon.patch
+patches    += $(CURDIR)/patches/webkitgtk-2.40.1-i386-sse.patch
+patches    += $(CURDIR)/patches/webkitgtk-2.40.1-mips-atomic.patch
 patches    += $(CURDIR)/patches/webkitgtk-2.40.1-bwrap-cross.patch
 patches    += $(CURDIR)/patches/webkitgtk-2.40.1-source-brush.patch
 
@@ -52,6 +54,8 @@
 $(patches): $(sha1s)
 	@echo -e "\n======= Create Patches =======\n" ; \
 	 ( cd create-2.40.1-arm-neon-patch     ; ./create.patch.sh ) ; \
+	 ( cd create-2.40.1-i386-sse-patch     ; ./create.patch.sh ) ; \
+	 ( cd create-2.40.1-mips-atomic-patch  ; ./create.patch.sh ) ; \
 	 ( cd create-2.40.1-bwrap-cross-patch  ; ./create.patch.sh ) ; \
 	 ( cd create-2.40.1-source-brush-patch ; ./create.patch.sh ) ; \
 	 echo -e "\n"
Index: sources/packages/x/webkitgtk/create-2.40.1-bwrap-cross-patch/file.list
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-bwrap-cross-patch/file.list	(revision 88)
+++ sources/packages/x/webkitgtk/create-2.40.1-bwrap-cross-patch/file.list	(revision 89)
@@ -1,6 +1 @@
-webkitgtk-2.40.1-new
-└── Source
-    └── cmake
-        └── BubblewrapSandboxChecks.cmake
-
-2 directories, 1 file
+webkitgtk-2.40.1/Source/cmake/BubblewrapSandboxChecks.cmake
Index: sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/create.patch.sh
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/create.patch.sh	(nonexistent)
+++ sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/create.patch.sh	(revision 89)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=2.40.1
+
+tar --files-from=file.list -xJvf ../webkitgtk-$VERSION.tar.xz
+mv webkitgtk-$VERSION webkitgtk-$VERSION-orig
+
+cp -rf ./webkitgtk-$VERSION-new ./webkitgtk-$VERSION
+
+diff --unified -Nr  webkitgtk-$VERSION-orig  webkitgtk-$VERSION > webkitgtk-$VERSION-i386-sse.patch
+
+mv webkitgtk-$VERSION-i386-sse.patch ../patches
+
+rm -rf ./webkitgtk-$VERSION
+rm -rf ./webkitgtk-$VERSION-orig

Property changes on: sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/file.list
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/file.list	(nonexistent)
+++ sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/file.list	(revision 89)
@@ -0,0 +1 @@
+webkitgtk-2.40.1/Source/ThirdParty/ANGLE/src/common/platform.h
Index: sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/webkitgtk-2.40.1-new/Source/ThirdParty/ANGLE/src/common/platform.h
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/webkitgtk-2.40.1-new/Source/ThirdParty/ANGLE/src/common/platform.h	(nonexistent)
+++ sources/packages/x/webkitgtk/create-2.40.1-i386-sse-patch/webkitgtk-2.40.1-new/Source/ThirdParty/ANGLE/src/common/platform.h	(revision 89)
@@ -0,0 +1,209 @@
+//
+// Copyright 2014 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.
+//
+
+// platform.h: Operating system specific includes and defines.
+
+#ifndef COMMON_PLATFORM_H_
+#define COMMON_PLATFORM_H_
+
+#if defined(_WIN32)
+#    define ANGLE_PLATFORM_WINDOWS 1
+#elif defined(__Fuchsia__)
+#    define ANGLE_PLATFORM_FUCHSIA 1
+#    define ANGLE_PLATFORM_POSIX 1
+#elif defined(__APPLE__)
+#    define ANGLE_PLATFORM_APPLE 1
+#    define ANGLE_PLATFORM_POSIX 1
+#elif defined(ANDROID)
+#    define ANGLE_PLATFORM_ANDROID 1
+#    define ANGLE_PLATFORM_POSIX 1
+#elif defined(__ggp__)
+#    define ANGLE_PLATFORM_GGP 1
+#    define ANGLE_PLATFORM_POSIX 1
+#elif defined(__linux__) || defined(EMSCRIPTEN)
+#    define ANGLE_PLATFORM_LINUX 1
+#    define ANGLE_PLATFORM_POSIX 1
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) ||              \
+    defined(__DragonFly__) || defined(__sun) || defined(__GLIBC__) || defined(__GNU__) || \
+    defined(__QNX__) || defined(__Fuchsia__) || defined(__HAIKU__)
+#    define ANGLE_PLATFORM_POSIX 1
+#else
+#    error Unsupported platform.
+#endif
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+#    ifndef STRICT
+#        define STRICT 1
+#    endif
+#    ifndef WIN32_LEAN_AND_MEAN
+#        define WIN32_LEAN_AND_MEAN 1
+#    endif
+#    ifndef NOMINMAX
+#        define NOMINMAX 1
+#    endif
+
+#    include <intrin.h>
+
+#    if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
+#        define ANGLE_ENABLE_WINDOWS_UWP 1
+#    endif
+
+#    if defined(ANGLE_ENABLE_D3D9)
+#        include <d3d9.h>
+#        include <d3dcompiler.h>
+#    endif
+
+// Include D3D11 headers when OpenGL is enabled on Windows for interop extensions.
+#    if defined(ANGLE_ENABLE_D3D11) || defined(ANGLE_ENABLE_OPENGL)
+#        include <d3d10_1.h>
+#        include <d3d11.h>
+#        include <d3d11_3.h>
+#        include <d3d11on12.h>
+#        include <d3d12.h>
+#        include <d3dcompiler.h>
+#        include <dxgi.h>
+#        include <dxgi1_2.h>
+#        include <dxgi1_4.h>
+#    endif
+
+#    if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+#        include <wrl.h>
+#    endif
+
+#    if defined(ANGLE_ENABLE_WINDOWS_UWP)
+#        include <dxgi1_3.h>
+#        if defined(_DEBUG)
+#            include <DXProgrammableCapture.h>
+#            include <dxgidebug.h>
+#        endif
+#    endif
+
+// Include <windows.h> to ensure tests related files can be built when building
+// vulkan only backend ANGLE on windows.
+#    if defined(ANGLE_ENABLE_VULKAN)
+#        include <windows.h>
+#    endif
+
+// Macros 'near', 'far', 'NEAR' and 'FAR' are defined by 'shared/minwindef.h' in the Windows SDK.
+// Macros 'near' and 'far' are empty. They are not used by other Windows headers and are undefined
+// here to avoid identifier conflicts. Macros 'NEAR' and 'FAR' contain 'near' and 'far'. They are
+// used by other Windows headers and are cleared here to avoid compilation errors.
+#    undef near
+#    undef far
+#    undef NEAR
+#    undef FAR
+#    define NEAR
+#    define FAR
+#endif
+
+#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64)
+#    include <intrin.h>
+#    define ANGLE_USE_SSE
+#elif defined(__GNUC__) && defined(__x86_64__)
+#    include <x86intrin.h>
+#    define ANGLE_USE_SSE
+#endif
+
+// Mips and arm devices need to include stddef for size_t.
+#if defined(__mips__) || defined(__arm__) || defined(__aarch64__)
+#    include <stddef.h>
+#endif
+
+// The MemoryBarrier function name collides with a macro under Windows
+// We will undef the macro so that the function name does not get replaced
+#undef MemoryBarrier
+
+// Macro for hinting that an expression is likely to be true/false.
+#if !defined(ANGLE_LIKELY) || !defined(ANGLE_UNLIKELY)
+#    if defined(__GNUC__) || defined(__clang__)
+#        define ANGLE_LIKELY(x) __builtin_expect(!!(x), 1)
+#        define ANGLE_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#    else
+#        define ANGLE_LIKELY(x) (x)
+#        define ANGLE_UNLIKELY(x) (x)
+#    endif  // defined(__GNUC__) || defined(__clang__)
+#endif      // !defined(ANGLE_LIKELY) || !defined(ANGLE_UNLIKELY)
+
+#ifdef ANGLE_PLATFORM_APPLE
+#    include <TargetConditionals.h>
+#    if TARGET_OS_OSX
+#        define ANGLE_PLATFORM_MACOS 1
+#    elif TARGET_OS_IPHONE
+#        define ANGLE_PLATFORM_IOS 1
+#        if TARGET_OS_SIMULATOR
+#            define ANGLE_PLATFORM_IOS_SIMULATOR 1
+#        endif
+#        if TARGET_OS_MACCATALYST
+#            define ANGLE_PLATFORM_MACCATALYST 1
+#        endif
+#    elif TARGET_OS_WATCH
+#        define ANGLE_PLATFORM_WATCHOS 1
+#        if TARGET_OS_SIMULATOR
+#            define ANGLE_PLATFORM_IOS_SIMULATOR 1
+#        endif
+#    elif TARGET_OS_TV
+#        define ANGLE_PLATFORM_APPLETV 1
+#        if TARGET_OS_SIMULATOR
+#            define ANGLE_PLATFORM_IOS_SIMULATOR 1
+#        endif
+#    endif
+#    // This might be useful globally. At the moment it is used
+#    // to differentiate MacCatalyst on Intel and Apple Silicon.
+#    if defined(__arm64__) || defined(__aarch64__)
+#        define ANGLE_CPU_ARM64 1
+#    endif
+#    // EAGL should be enabled on iOS, but not Mac Catalyst unless it is running on Apple Silicon.
+#    if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || \
+        (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64))
+#        define ANGLE_ENABLE_EAGL
+#    endif
+#    // Identify Metal API >= what shipped on macOS Catalina.
+#    if (defined(ANGLE_PLATFORM_MACOS) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500) || \
+        (defined(ANGLE_PLATFORM_IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000)
+#        define ANGLE_WITH_MODERN_METAL_API 1
+#    endif
+#endif
+
+// Define ANGLE_WITH_ASAN macro.
+#if defined(__has_feature)
+#    if __has_feature(address_sanitizer)
+#        define ANGLE_WITH_ASAN 1
+#    endif
+#endif
+
+// Define ANGLE_WITH_MSAN macro.
+#if defined(__has_feature)
+#    if __has_feature(memory_sanitizer)
+#        define ANGLE_WITH_MSAN 1
+#    endif
+#endif
+
+// Define ANGLE_WITH_TSAN macro.
+#if defined(__has_feature)
+#    if __has_feature(thread_sanitizer)
+#        define ANGLE_WITH_TSAN 1
+#    endif
+#endif
+
+// Define ANGLE_WITH_UBSAN macro.
+#if defined(__has_feature)
+#    if __has_feature(undefined_behavior_sanitizer)
+#        define ANGLE_WITH_UBSAN 1
+#    endif
+#endif
+
+#if defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN) || defined(ANGLE_WITH_UBSAN)
+#    define ANGLE_WITH_SANITIZER 1
+#endif  // defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN) || defined(ANGLE_WITH_UBSAN)
+
+#include <stdint.h>
+#if INTPTR_MAX == INT64_MAX
+#    define ANGLE_IS_64_BIT_CPU 1
+#else
+#    define ANGLE_IS_32_BIT_CPU 1
+#endif
+
+#endif  // COMMON_PLATFORM_H_
Index: sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/create.patch.sh
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/create.patch.sh	(nonexistent)
+++ sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/create.patch.sh	(revision 89)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=2.40.1
+
+tar --files-from=file.list -xJvf ../webkitgtk-$VERSION.tar.xz
+mv webkitgtk-$VERSION webkitgtk-$VERSION-orig
+
+cp -rf ./webkitgtk-$VERSION-new ./webkitgtk-$VERSION
+
+diff --unified -Nr  webkitgtk-$VERSION-orig  webkitgtk-$VERSION > webkitgtk-$VERSION-mips-atomic.patch
+
+mv webkitgtk-$VERSION-mips-atomic.patch ../patches
+
+rm -rf ./webkitgtk-$VERSION
+rm -rf ./webkitgtk-$VERSION-orig

Property changes on: sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/file.list
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/file.list	(nonexistent)
+++ sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/file.list	(revision 89)
@@ -0,0 +1 @@
+webkitgtk-2.40.1/Source/ThirdParty/ANGLE/src/libANGLE/renderer/serial_utils.h
Index: sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/webkitgtk-2.40.1-new/Source/ThirdParty/ANGLE/src/libANGLE/renderer/serial_utils.h
===================================================================
--- sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/webkitgtk-2.40.1-new/Source/ThirdParty/ANGLE/src/libANGLE/renderer/serial_utils.h	(nonexistent)
+++ sources/packages/x/webkitgtk/create-2.40.1-mips-atomic-patch/webkitgtk-2.40.1-new/Source/ThirdParty/ANGLE/src/libANGLE/renderer/serial_utils.h	(revision 89)
@@ -0,0 +1,297 @@
+//
+// Copyright 2019 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.
+//
+// serial_utils:
+//   Utilities for generating unique IDs for resources in ANGLE.
+//
+
+#ifndef LIBANGLE_RENDERER_SERIAL_UTILS_H_
+#define LIBANGLE_RENDERER_SERIAL_UTILS_H_
+
+#include <array>
+#include <atomic>
+#include <limits>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+namespace rx
+{
+class ResourceSerial
+{
+  public:
+    constexpr ResourceSerial() : mValue(kDirty) {}
+    explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {}
+    constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; }
+    constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; }
+
+    void dirty() { mValue = kDirty; }
+    void clear() { mValue = kEmpty; }
+
+    constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
+    constexpr bool empty() const { return mValue == kEmpty; }
+
+  private:
+    constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max();
+    constexpr static uintptr_t kEmpty = 0;
+
+    uintptr_t mValue;
+};
+
+// Class UniqueSerial defines unique serial number for object identification. It has only
+// equal/unequal comparison but no greater/smaller comparison. The default constructor creates an
+// invalid value.
+class UniqueSerial final
+{
+  public:
+    constexpr UniqueSerial() : mValue(kInvalid) {}
+    constexpr UniqueSerial(const UniqueSerial &other)  = default;
+    UniqueSerial &operator=(const UniqueSerial &other) = default;
+
+    constexpr bool operator==(const UniqueSerial &other) const
+    {
+        return mValue != kInvalid && mValue == other.mValue;
+    }
+    constexpr bool operator!=(const UniqueSerial &other) const
+    {
+        return mValue == kInvalid || mValue != other.mValue;
+    }
+
+    // Useful for serialization.
+    constexpr uint64_t getValue() const { return mValue; }
+    constexpr bool valid() const { return mValue != kInvalid; }
+
+  private:
+    friend class UniqueSerialFactory;
+    constexpr explicit UniqueSerial(uint64_t value) : mValue(value) {}
+    uint64_t mValue;
+    static constexpr uint64_t kInvalid = 0;
+};
+
+class UniqueSerialFactory final : angle::NonCopyable
+{
+  public:
+    UniqueSerialFactory() : mSerial(1) {}
+
+    UniqueSerial generate()
+    {
+        uint64_t current = mSerial++;
+        ASSERT(mSerial > current);  // Integer overflow
+        return UniqueSerial(current);
+    }
+
+  private:
+    uint64_t mSerial;
+};
+
+// Class Serial defines a monotonically increasing serial number that indicates the timeline of
+// execution.
+class Serial final
+{
+  public:
+    constexpr Serial() : mValue(0) {}
+    constexpr Serial(const Serial &other)  = default;
+    Serial &operator=(const Serial &other) = default;
+
+    static constexpr Serial Infinite() { return Serial(std::numeric_limits<uint64_t>::max()); }
+
+    constexpr bool operator==(const Serial &other) const { return mValue == other.mValue; }
+    constexpr bool operator!=(const Serial &other) const { return mValue != other.mValue; }
+    constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; }
+    constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; }
+    constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; }
+    constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; }
+
+    // Useful for serialization.
+    constexpr uint64_t getValue() const { return mValue; }
+
+  private:
+    friend class AtomicSerialFactory;
+    friend class RangedSerialFactory;
+    friend class AtomicQueueSerial;
+    constexpr explicit Serial(uint64_t value) : mValue(value) {}
+    uint64_t mValue;
+};
+
+// Defines class to track the queue serial that can be load/store from multiple threads atomically.
+class AtomicQueueSerial final
+{
+  public:
+    AtomicQueueSerial &operator=(const Serial &other)
+    {
+        mValue.store(other.mValue, std::memory_order_release);
+        return *this;
+    }
+    Serial getSerial() const { return Serial(mValue.load(std::memory_order_consume)); }
+
+  private:
+    static constexpr uint64_t kInvalid = 0;
+    std::atomic<uint64_t> mValue       = kInvalid;
+};
+
+// Used as default/initial serial
+static constexpr Serial kZeroSerial = Serial();
+
+// The factory to generate a serial number within the range [mSerial, mSerial+mCount}
+class RangedSerialFactory final : angle::NonCopyable
+{
+  public:
+    RangedSerialFactory() : mSerial(0), mCount(0) {}
+
+    void reset() { mCount = 0; }
+    bool empty() const { return mCount == 0; }
+    bool generate(Serial *serialOut)
+    {
+        if (mCount > 0)
+        {
+            uint64_t current = mSerial++;
+            ASSERT(mSerial > current);  // Integer overflow
+            *serialOut = Serial(current);
+            mCount--;
+            return true;
+        }
+        return false;
+    }
+
+  private:
+    friend class AtomicSerialFactory;
+    void initialize(uint64_t initialSerial, size_t count)
+    {
+        mSerial = initialSerial;
+        mCount  = count;
+    }
+    uint64_t mSerial;
+    size_t mCount;
+};
+
+class AtomicSerialFactory final : angle::NonCopyable
+{
+  public:
+    AtomicSerialFactory() : mSerial(1) {}
+
+    Serial generate()
+    {
+        uint64_t current = mSerial++;
+        ASSERT(mSerial > current);  // Integer overflow
+        return Serial(current);
+    }
+
+    void reserve(RangedSerialFactory *rangeFactory, size_t count)
+    {
+        uint64_t current = mSerial;
+        mSerial += count;
+        ASSERT(mSerial > current);  // Integer overflow
+        rangeFactory->initialize(current, count);
+    }
+
+  private:
+    std::atomic<uint64_t> mSerial;
+};
+
+// For backend that supports multiple queue serials, QueueSerial includes a Serial and an index.
+using SerialIndex                                     = uint32_t;
+static constexpr SerialIndex kInvalidQueueSerialIndex = SerialIndex(-1);
+
+class QueueSerial;
+// Because we release queue index when context becomes non-current, in order to use up all index
+// count, you will need to have 256 threads each has a context current. This is not a reasonable
+// usage case.
+constexpr size_t kMaxQueueSerialIndexCount = 256;
+// Fixed array of queue serials
+class AtomicQueueSerialFixedArray final
+{
+  public:
+    AtomicQueueSerialFixedArray()  = default;
+    ~AtomicQueueSerialFixedArray() = default;
+
+    void setQueueSerial(SerialIndex index, Serial serial);
+    void setQueueSerial(const QueueSerial &queueSerial);
+    void fill(Serial serial) { std::fill(mSerials.begin(), mSerials.end(), serial); }
+    Serial operator[](SerialIndex index) const { return mSerials[index].getSerial(); }
+    size_t size() const { return mSerials.size(); }
+
+  private:
+    std::array<AtomicQueueSerial, kMaxQueueSerialIndexCount> mSerials;
+};
+
+class QueueSerial final
+{
+  public:
+    QueueSerial() : mIndex(kInvalidQueueSerialIndex) {}
+    QueueSerial(SerialIndex index, Serial serial) : mIndex(index), mSerial(serial)
+    {
+        ASSERT(index != kInvalidQueueSerialIndex);
+    }
+    constexpr QueueSerial(const QueueSerial &other)  = default;
+    QueueSerial &operator=(const QueueSerial &other) = default;
+
+    constexpr bool operator==(const QueueSerial &other) const
+    {
+        return mIndex == other.mIndex && mSerial == other.mSerial;
+    }
+    constexpr bool operator!=(const QueueSerial &other) const
+    {
+        return mIndex != other.mIndex || mSerial != other.mSerial;
+    }
+    constexpr bool operator<(const QueueSerial &other) const
+    {
+        ASSERT(mIndex != kInvalidQueueSerialIndex);
+        ASSERT(mIndex == other.mIndex);
+        return mSerial < other.mSerial;
+    }
+    constexpr bool operator<=(const QueueSerial &other) const
+    {
+        ASSERT(mIndex != kInvalidQueueSerialIndex);
+        ASSERT(mIndex == other.mIndex);
+        return mSerial <= other.mSerial;
+    }
+    constexpr bool operator>(const QueueSerial &other) const
+    {
+        ASSERT(mIndex != kInvalidQueueSerialIndex);
+        ASSERT(mIndex == other.mIndex);
+        return mSerial > other.mSerial;
+    }
+    constexpr bool operator>=(const QueueSerial &other) const
+    {
+        ASSERT(mIndex != kInvalidQueueSerialIndex);
+        ASSERT(mIndex == other.mIndex);
+        return mSerial >= other.mSerial;
+    }
+
+    bool operator>(const AtomicQueueSerialFixedArray &serials) const
+    {
+        return mSerial > serials[mIndex];
+    }
+    bool operator<=(const AtomicQueueSerialFixedArray &serials) const
+    {
+        return mSerial <= serials[mIndex];
+    }
+
+    constexpr bool valid() const { return mIndex != kInvalidQueueSerialIndex; }
+
+    SerialIndex getIndex() const { return mIndex; }
+    Serial getSerial() const { return mSerial; }
+
+  private:
+    SerialIndex mIndex;
+    Serial mSerial;
+};
+
+ANGLE_INLINE void AtomicQueueSerialFixedArray::setQueueSerial(SerialIndex index, Serial serial)
+{
+    ASSERT(index != kInvalidQueueSerialIndex);
+    ASSERT(index < mSerials.size());
+    // Serial can only increase
+    ASSERT(serial > mSerials[index].getSerial());
+    mSerials[index] = serial;
+}
+
+ANGLE_INLINE void AtomicQueueSerialFixedArray::setQueueSerial(const QueueSerial &queueSerial)
+{
+    setQueueSerial(queueSerial.getIndex(), queueSerial.getSerial());
+}
+}  // namespace rx
+
+#endif  // LIBANGLE_RENDERER_SERIAL_UTILS_H_