| // |
| // 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. |
| // |
| // Overlay.cpp: |
| // Implements the Overlay class. |
| // |
| |
| #include "libANGLE/Overlay.h" |
| |
| #include "common/string_utils.h" |
| #include "common/system_utils.h" |
| #include "libANGLE/Context.h" |
| #include "libANGLE/Overlay_font_autogen.h" |
| #include "libANGLE/renderer/GLImplFactory.h" |
| #include "libANGLE/renderer/OverlayImpl.h" |
| |
| #include <numeric> |
| |
| namespace gl |
| { |
| namespace |
| { |
| #define ANGLE_WIDGET_NAME_PROC(WIDGET_ID) {ANGLE_STRINGIFY(WIDGET_ID), WidgetId::WIDGET_ID}, |
| |
| constexpr std::pair<const char *, WidgetId> kWidgetNames[] = { |
| ANGLE_WIDGET_ID_X(ANGLE_WIDGET_NAME_PROC)}; |
| } // namespace |
| |
| OverlayState::OverlayState() : mEnabledWidgetCount(0), mOverlayWidgets{} {} |
| OverlayState::~OverlayState() = default; |
| |
| Overlay::Overlay(rx::GLImplFactory *factory) |
| : mLastPerSecondUpdate(0), mImplementation(factory->createOverlay(mState)) |
| {} |
| Overlay::~Overlay() = default; |
| |
| angle::Result Overlay::init(const Context *context) |
| { |
| initOverlayWidgets(); |
| mLastPerSecondUpdate = angle::GetCurrentSystemTime(); |
| |
| ASSERT(std::all_of( |
| mState.mOverlayWidgets.begin(), mState.mOverlayWidgets.end(), |
| [](const std::unique_ptr<overlay::Widget> &widget) { return widget.get() != nullptr; })); |
| |
| enableOverlayWidgetsFromEnvironment(); |
| |
| bool success = false; |
| ANGLE_TRY(mImplementation->init(context, &success)); |
| if (!success) |
| { |
| mState.mEnabledWidgetCount = 0; |
| } |
| return angle::Result::Continue; |
| } |
| |
| void Overlay::destroy(const gl::Context *context) |
| { |
| ASSERT(mImplementation); |
| mImplementation->onDestroy(context); |
| } |
| |
| void Overlay::enableOverlayWidgetsFromEnvironment() |
| { |
| std::vector<std::string> enabledWidgets = angle::GetStringsFromEnvironmentVarOrAndroidProperty( |
| "ANGLE_OVERLAY", "debug.angle.overlay", ":"); |
| |
| for (const std::pair<const char *, WidgetId> &widgetName : kWidgetNames) |
| { |
| if (std::find(enabledWidgets.begin(), enabledWidgets.end(), widgetName.first) != |
| enabledWidgets.end()) |
| { |
| mState.mOverlayWidgets[widgetName.second]->enabled = true; |
| ++mState.mEnabledWidgetCount; |
| } |
| } |
| } |
| |
| void Overlay::onSwap() const |
| { |
| // Increment FPS counter. |
| getPerSecondWidget(WidgetId::FPS)->add(1); |
| |
| // Update per second values every second. |
| double currentTime = angle::GetCurrentSystemTime(); |
| double timeDiff = currentTime - mLastPerSecondUpdate; |
| if (timeDiff >= 1.0) |
| { |
| for (const std::unique_ptr<overlay::Widget> &widget : mState.mOverlayWidgets) |
| { |
| if (widget->type == WidgetType::PerSecond) |
| { |
| overlay::PerSecond *perSecond = |
| reinterpret_cast<overlay::PerSecond *>(widget.get()); |
| perSecond->lastPerSecondCount = static_cast<size_t>(perSecond->count / timeDiff); |
| perSecond->count = 0; |
| } |
| } |
| mLastPerSecondUpdate += 1.0; |
| } |
| } |
| |
| MockOverlay::MockOverlay(rx::GLImplFactory *implFactory) {} |
| MockOverlay::~MockOverlay() = default; |
| |
| } // namespace gl |