# Codec common sources
add_subdirectory(apigen-codec-common)
add_subdirectory(compressedTextureFormats)

# GL
add_subdirectory(gl)

# Vulkan
add_subdirectory(vulkan)

# RenderControl decoder
add_subdirectory(renderControl_dec)

# Magma decoder
add_subdirectory(magma)

# Stream server core
set(stream-server-core-sources
    Buffer.cpp
    ColorBuffer.cpp
    GfxStreamAgents.cpp
    VirtioGpuTimelines.cpp
    VsyncThread.cpp
    ChannelStream.cpp
    DisplaySurface.cpp
    DisplaySurfaceUser.cpp
    Hwc2.cpp
    PostWorker.cpp
    ReadBuffer.cpp
    render_api.cpp
    RenderChannelImpl.cpp
    RenderThreadInfo.cpp
    RenderThreadInfoGl.cpp
    RenderThreadInfoMagma.cpp
    RingStream.cpp
    SyncThread.cpp
    RenderThread.cpp
    RenderControl.cpp
    RenderWindow.cpp
    RenderLibImpl.cpp
    RendererImpl.cpp
    FrameBuffer.cpp)
if (APPLE)
    set(stream-server-core-platform-sources NativeSubWindow_cocoa.m)
elseif (WIN32)
    set(stream-server-core-platform-sources NativeSubWindow_win32.cpp)
else()
    set(stream-server-core-platform-sources NativeSubWindow_x11.cpp)
endif()

# Compile everything as a static library first so that unit tests can call non-exported functions
add_library(
        gfxstream_backend_static
        STATIC
        ${stream-server-core-sources}
        ${stream-server-core-platform-sources}
)
target_link_libraries(
        gfxstream_backend_static
        PUBLIC
        GLES_CM_translator_static
        OpenGLESDispatch
        renderControl_dec
        gfxstream-gl-server
        gfxstream-magma-server
        gfxstream-vulkan-server
        gfxstream_egl_headers
        gfxstream-snapshot
        apigen-codec-common
        ${GFXSTREAM_HOST_COMMON_LIB}
        ${GFXSTREAM_BASE_LIB})

target_include_directories(
        gfxstream_backend_static
        PUBLIC
        ${GFXSTREAM_REPO_ROOT}
        ${GFXSTREAM_REPO_ROOT}/include
        ${GFXSTREAM_REPO_ROOT}/stream-servers
        ${GFXSTREAM_REPO_ROOT}/stream-servers/apigen-codec-common
        ${GFXSTREAM_REPO_ROOT}/stream-servers/gl
        ${GFXSTREAM_REPO_ROOT}/stream-servers/gl/glestranslator/include
        ${GFXSTREAM_REPO_ROOT}/stream-servers/magma
        ${GFXSTREAM_REPO_ROOT}/stream-servers/magma/magma_dec
        ${GFXSTREAM_REPO_ROOT}/stream-servers/vulkan
        ${GFXSTREAM_REPO_ROOT}/third-party/fuchsia/magma/include
        ${GFXSTREAM_REPO_ROOT}/third-party/glm/include)

if (APPLE)
    target_link_libraries(gfxstream_backend_static PUBLIC "-framework AppKit -framework QuartzCore -framework IOSurface")
endif()
if (WIN32)
    target_link_libraries(gfxstream_backend_static PRIVATE D3d9.lib)
endif()

# Suppress some warnings generated by platform/aemu repo
target_compile_options(
    gfxstream_backend_static
    PRIVATE
    -Wno-invalid-offsetof
    -Wno-free-nonheap-object
    -Wno-attributes
    )

# gfxstream_backend.dll
add_library(
    gfxstream_backend
    SHARED
    virtio-gpu-gfxstream-renderer.cpp)

target_link_libraries(
    gfxstream_backend
    PUBLIC
    gfxstream_backend_static
    PRIVATE
    )

if(BUILD_STANDALONE)
    target_link_libraries(gfxstream_backend
        PRIVATE
        gfxstream-gl-host-common)
endif()

if (APPLE)
    set_target_properties(gfxstream_backend
        PROPERTIES
        LINK_FLAGS  "-undefined dynamic_lookup -flat_namespace")
endif()

android_install_shared(gfxstream_backend)

# Testing libraries
add_subdirectory(testlibs)

if (ENABLE_VKCEREAL_TESTS)

set(LIST_OF_TESTS)
function(discover_tests test_name)
if (WIN32)
    gtest_discover_tests(
        ${test_name}
        ${ARGN})
    list(APPEND LIST_OF_TESTS ${test_name})
    set(LIST_OF_TESTS ${LIST_OF_TESTS} PARENT_SCOPE)
else()
    gtest_discover_tests(
        ${test_name}
        ${ARGN}
    )
endif()
endfunction()
    # Backend unit tests
    add_executable(
        gfxstream_backend_unittests
        gfxstream_unittest.cpp)
    target_link_libraries(
        gfxstream_backend_unittests
        PRIVATE
        OSWindow
        gfxstream_backend
        aemu-host-common-testing-support
        ${GFXSTREAM_BASE_LIB}
        gtest_main)
        discover_tests(gfxstream_backend_unittests)

    # More functional tests#########################################################

    # Common testing support library################################################
    # This includes the server core and testing sources
    add_library(
        stream-server-testing-support
        tests/SampleApplication.cpp
        tests/GLSnapshotTesting.cpp
        tests/OpenGLTestContext.cpp
        tests/GLTestUtils.cpp
        tests/ShaderUtils.cpp
        tests/GLSnapshotTestDispatch.cpp
        tests/GLSnapshotTestStateUtils.cpp
        tests/HelloTriangleImp.cpp
        tests/ImageUtils.cpp)
    target_include_directories(
        stream-server-testing-support
        PUBLIC
        ${GFXSTREAM_REPO_ROOT}
        ${GFXSTREAM_REPO_ROOT}/include
        ${GFXSTREAM_REPO_ROOT}/stream-servers
        ${GFXSTREAM_REPO_ROOT}/stream-servers/gl/glestranslator/GLES_CM
        ${GFXSTREAM_REPO_ROOT}/stream-servers/gl/glestranslator/include
        ${GFXSTREAM_REPO_ROOT}/stream-servers/apigen-codec-common
        ${GFXSTREAM_REPO_ROOT}/stream-servers/vulkan)
    target_link_libraries(
        stream-server-testing-support
        PUBLIC
        aemu-host-common-testing-support
        aemu-base-testing-support
        gfxstream_backend_static
        gfxstream_stb
        OSWindow
        gtest)

    if (LINUX)
    add_library(
        x11_testing_support
        tests/X11TestingSupport.cpp)
    target_link_libraries(
        x11_testing_support
        aemu-base.headers)
    endif()

    # Basic opengl rendering tests##################################################
    add_executable(
        OpenglRender_unittests
        tests/FrameBuffer_unittest.cpp
        tests/GLES1Dispatch_unittest.cpp
        tests/DefaultFramebufferBlit_unittest.cpp
        tests/TextureDraw_unittest.cpp
        tests/StalePtrRegistry_unittest.cpp
        tests/VsyncThread_unittest.cpp)
    target_link_libraries(
        OpenglRender_unittests
        PRIVATE
        stream-server-testing-support
        aemu-host-common-testing-support
        aemu-base-testing-support
        gfxstream_backend_static
        gtest_main)
    if (LINUX)
        target_compile_definitions(
            OpenglRender_unittests
            PRIVATE GFXSTREAM_HAS_X11=1)
        target_link_libraries(
            OpenglRender_unittests
            PRIVATE x11_testing_support)
    endif()
    discover_tests(OpenglRender_unittests)

    # Snapshot tests################################################################
    add_executable(
        OpenglRender_snapshot_unittests
        tests/GLSnapshotBuffers_unittest.cpp
        tests/GLSnapshotFramebufferControl_unittest.cpp
        tests/GLSnapshotFramebuffers_unittest.cpp
        tests/GLSnapshotMultisampling_unittest.cpp
        tests/GLSnapshotPixelOperations_unittest.cpp
        tests/GLSnapshotPixels_unittest.cpp
        tests/GLSnapshotPrograms_unittest.cpp
        tests/GLSnapshotRasterization_unittest.cpp
        tests/GLSnapshotRenderbuffers_unittest.cpp
        tests/GLSnapshotRendering_unittest.cpp
        tests/GLSnapshotShaders_unittest.cpp
        tests/GLSnapshotTextures_unittest.cpp
        tests/GLSnapshotTransformation_unittest.cpp
        tests/GLSnapshotVertexAttributes_unittest.cpp
        tests/GLSnapshot_unittest.cpp)
    target_link_libraries(
        OpenglRender_snapshot_unittests
        PRIVATE
        stream-server-testing-support
        aemu-host-common-testing-support
        aemu-base-testing-support
        gfxstream_backend_static
        gtest_main)
    discover_tests(OpenglRender_snapshot_unittests)

    # Vulkan tests##################################################################
    add_executable(
        Vulkan_unittests
        tests/Vulkan_unittest.cpp
        tests/CompositorVk_unittest.cpp
        tests/SwapChainStateVk_unittest.cpp
        tests/DisplayVk_unittest.cpp
        tests/VirtioGpuTimelines_unittest.cpp
        vulkan/vk_util_unittest.cpp
        vulkan/VkFormatUtils_unittest.cpp
        vulkan/VkQsriTimeline_unittest.cpp
        vulkan/VkDecoderGlobalState_unittest.cpp
    )
    target_link_libraries(
        Vulkan_unittests
        PRIVATE
        stream-server-testing-support
        aemu-host-common-testing-support
        aemu-base-testing-support
        gfxstream_backend_static
        gtest
        gtest_main
        gmock)
    if (APPLE)
        target_compile_definitions(Vulkan_unittests PRIVATE -DVK_USE_PLATFORM_METAL_EXT)
        target_link_libraries(Vulkan_unittests PUBLIC "-framework AppKit")
    endif()
    discover_tests(
            Vulkan_unittests
            WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

    if (APPLE)
        target_compile_definitions(Vulkan_unittests PRIVATE -DVK_USE_PLATFORM_METAL_EXT)
    elseif (UNIX)
        target_compile_definitions(Vulkan_unittests PRIVATE -DVK_USE_PLATFORM_XCB_KHR)
    endif()


    file(GLOB Vulkan_unittests_datafiles "tests/testdata/*.png")
    add_custom_command(TARGET Vulkan_unittests POST_BUILD
                       COMMAND ${CMAKE_COMMAND} -E make_directory
                            ${CMAKE_BINARY_DIR}/tests/testdata
                       COMMAND ${CMAKE_COMMAND} -E copy_if_different
                            ${Vulkan_unittests_datafiles}
                            ${CMAKE_BINARY_DIR}/tests/testdata)

    add_executable(
            Vulkan_integrationtests
            vulkan/testing/VkDecoderTestDispatch.h
            vulkan/testing/VulkanTestHelper.cpp
    )
    target_link_libraries(
            Vulkan_integrationtests
            PRIVATE
            gfxstream_backend_static
            gfxstream-gl-server
            gfxstream-vulkan-server
            stream-server-testing-support
            gtest
            gtest_main
            gmock)
    discover_tests(Vulkan_integrationtests)
endif()
if (WIN32)
    set(BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}")
    configure_file(../cmake/SetWin32TestEnvironment.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/SetWin32TestEnvironment.cmake @ONLY)
    set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES ${CMAKE_CURRENT_BINARY_DIR}/SetWin32TestEnvironment.cmake)
endif()
