Edit

kc3-lang/angle/samples/sample_util/SampleApplication.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2020-09-12 20:47:01
    Hash : eba501c8
    Message : Samples: Move frame counter to common location. Bug: angleproject:5040 Change-Id: I64f762b4eb5734f0768054a330a36e20ff9ba93e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2408713 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com>

  • samples/sample_util/SampleApplication.cpp
  • //
    // Copyright 2013 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.
    //
    
    #include "SampleApplication.h"
    
    #include "common/debug.h"
    #include "util/EGLWindow.h"
    #include "util/gles_loader_autogen.h"
    #include "util/random_utils.h"
    #include "util/shader_utils.h"
    #include "util/test_utils.h"
    #include "util/util_gl.h"
    
    #include <string.h>
    #include <iostream>
    #include <utility>
    
    #if defined(ANGLE_PLATFORM_WINDOWS)
    #    include "util/windows/WGLWindow.h"
    #endif  // defined(ANGLE_PLATFORM_WINDOWS)
    
    namespace
    {
    const char *kUseAngleArg = "--use-angle=";
    const char *kUseGlArg    = "--use-gl=native";
    
    using DisplayTypeInfo = std::pair<const char *, EGLint>;
    
    const DisplayTypeInfo kDisplayTypes[] = {
        {"d3d9", EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE},
        {"d3d11", EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE},
        {"gl", EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE},
        {"gles", EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE},
        {"metal", EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE},
        {"null", EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE},
        {"swiftshader", EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE},
        {"vulkan", EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE},
    };
    
    EGLint GetDisplayTypeFromArg(const char *displayTypeArg)
    {
        for (const auto &displayTypeInfo : kDisplayTypes)
        {
            if (strcmp(displayTypeInfo.first, displayTypeArg) == 0)
            {
                std::cout << "Using ANGLE back-end API: " << displayTypeInfo.first << std::endl;
                return displayTypeInfo.second;
            }
        }
    
        std::cout << "Unknown ANGLE back-end API: " << displayTypeArg << std::endl;
        return EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
    }
    
    EGLint GetDeviceTypeFromArg(const char *displayTypeArg)
    {
        if (strcmp(displayTypeArg, "swiftshader") == 0)
        {
            return EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
        }
        else
        {
            return EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
        }
    }
    
    ANGLE_MAYBE_UNUSED bool IsGLExtensionEnabled(const std::string &extName)
    {
        return angle::CheckExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
                                           extName);
    }
    }  // anonymous namespace
    
    SampleApplication::SampleApplication(std::string name,
                                         int argc,
                                         char **argv,
                                         EGLint glesMajorVersion,
                                         EGLint glesMinorVersion,
                                         uint32_t width,
                                         uint32_t height)
        : mName(std::move(name)),
          mWidth(width),
          mHeight(height),
          mRunning(false),
          mFrameCount(0),
          mGLWindow(nullptr),
          mEGLWindow(nullptr),
          mOSWindow(nullptr),
          mDriverType(angle::GLESDriverType::AngleEGL)
    {
        mPlatformParams.renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
        bool useNativeGL         = false;
    
        for (int argIndex = 1; argIndex < argc; argIndex++)
        {
            if (strncmp(argv[argIndex], kUseAngleArg, strlen(kUseAngleArg)) == 0)
            {
                const char *arg            = argv[argIndex] + strlen(kUseAngleArg);
                mPlatformParams.renderer   = GetDisplayTypeFromArg(arg);
                mPlatformParams.deviceType = GetDeviceTypeFromArg(arg);
            }
    
            if (strncmp(argv[argIndex], kUseGlArg, strlen(kUseGlArg)) == 0)
            {
                useNativeGL = true;
            }
        }
    
        mOSWindow = OSWindow::New();
    
        // Load EGL library so we can initialize the display.
        if (useNativeGL)
        {
    #if defined(ANGLE_PLATFORM_WINDOWS)
            mGLWindow = WGLWindow::New(glesMajorVersion, glesMinorVersion);
            mEntryPointsLib.reset(angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));
            mDriverType = angle::GLESDriverType::SystemWGL;
    #else
            mGLWindow = EGLWindow::New(glesMajorVersion, glesMinorVersion);
            mEntryPointsLib.reset(
                angle::OpenSharedLibraryWithExtension(angle::GetNativeEGLLibraryNameWithExtension()));
            mDriverType = angle::GLESDriverType::SystemEGL;
    #endif  // defined(ANGLE_PLATFORM_WINDOWS)
        }
        else
        {
            mGLWindow = mEGLWindow = EGLWindow::New(glesMajorVersion, glesMinorVersion);
            mEntryPointsLib.reset(
                angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ApplicationDir));
        }
    }
    
    SampleApplication::~SampleApplication()
    {
        GLWindowBase::Delete(&mGLWindow);
        OSWindow::Delete(&mOSWindow);
    }
    
    bool SampleApplication::initialize()
    {
        return true;
    }
    
    void SampleApplication::destroy() {}
    
    void SampleApplication::step(float dt, double totalTime) {}
    
    void SampleApplication::draw() {}
    
    void SampleApplication::swap()
    {
        mGLWindow->swap();
    }
    
    OSWindow *SampleApplication::getWindow() const
    {
        return mOSWindow;
    }
    
    EGLConfig SampleApplication::getConfig() const
    {
        ASSERT(mEGLWindow);
        return mEGLWindow->getConfig();
    }
    
    EGLDisplay SampleApplication::getDisplay() const
    {
        ASSERT(mEGLWindow);
        return mEGLWindow->getDisplay();
    }
    
    EGLSurface SampleApplication::getSurface() const
    {
        ASSERT(mEGLWindow);
        return mEGLWindow->getSurface();
    }
    
    EGLContext SampleApplication::getContext() const
    {
        ASSERT(mEGLWindow);
        return mEGLWindow->getContext();
    }
    
    int SampleApplication::run()
    {
        if (!mOSWindow->initialize(mName, mWidth, mHeight))
        {
            return -1;
        }
    
        mOSWindow->setVisible(true);
    
        ConfigParameters configParams;
        configParams.redBits     = 8;
        configParams.greenBits   = 8;
        configParams.blueBits    = 8;
        configParams.alphaBits   = 8;
        configParams.depthBits   = 24;
        configParams.stencilBits = 8;
    
        if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mDriverType, mPlatformParams,
                                     configParams))
        {
            return -1;
        }
    
        // Disable vsync
        if (!mGLWindow->setSwapInterval(0))
        {
            return -1;
        }
    
        mRunning   = true;
        int result = 0;
    
    #if defined(ANGLE_ENABLE_ASSERTS)
        if (IsGLExtensionEnabled("GL_KHR_debug"))
        {
            EnableDebugCallback(this);
        }
    #endif
    
        if (!initialize())
        {
            mRunning = false;
            result   = -1;
        }
    
        mTimer.start();
        double prevTime = 0.0;
    
        while (mRunning)
        {
            double elapsedTime = mTimer.getElapsedTime();
            double deltaTime   = elapsedTime - prevTime;
    
            step(static_cast<float>(deltaTime), elapsedTime);
    
            // Clear events that the application did not process from this frame
            Event event;
            while (popEvent(&event))
            {
                // If the application did not catch a close event, close now
                switch (event.Type)
                {
                    case Event::EVENT_CLOSED:
                        exit();
                        break;
                    case Event::EVENT_KEY_RELEASED:
                        onKeyUp(event.Key);
                        break;
                    case Event::EVENT_KEY_PRESSED:
                        onKeyDown(event.Key);
                        break;
                    default:
                        break;
                }
            }
    
            if (!mRunning)
            {
                break;
            }
    
            draw();
            swap();
    
            mOSWindow->messageLoop();
    
            prevTime = elapsedTime;
    
            mFrameCount++;
    
            if (mFrameCount % 100 == 0)
            {
                printf("Rate: %0.2lf frames / second\n",
                       static_cast<double>(mFrameCount) / mTimer.getElapsedTime());
            }
        }
    
        destroy();
        mGLWindow->destroyGL();
        mOSWindow->destroy();
    
        return result;
    }
    
    void SampleApplication::exit()
    {
        mRunning = false;
    }
    
    bool SampleApplication::popEvent(Event *event)
    {
        return mOSWindow->popEvent(event);
    }
    
    void SampleApplication::onKeyUp(const Event::KeyEvent &keyEvent)
    {
        // Default no-op.
    }
    
    void SampleApplication::onKeyDown(const Event::KeyEvent &keyEvent)
    {
        // Default no-op.
    }