Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

port backendscope changes to release branch #9538

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/test-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ set(MBGL_TEST_FILES
test/programs/binary_program.test.cpp

# renderer
test/renderer/backend_scope.test.cpp
test/renderer/group_by_layout.test.cpp

# sprite
Expand Down
5 changes: 5 additions & 0 deletions include/mbgl/map/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <mbgl/map/map_observer.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/size.hpp>
#include <mbgl/util/util.hpp>

#include <memory>
#include <mutex>
Expand Down Expand Up @@ -80,4 +81,8 @@ class Backend : public MapObserver {
friend class BackendScope;
};

constexpr bool operator==(const Backend& a, const Backend& b) {
return &a == &b;
}

} // namespace mbgl
4 changes: 4 additions & 0 deletions include/mbgl/map/backend_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ class BackendScope {
static bool exists();

private:
void activate();
void deactivate();

BackendScope* priorScope;
BackendScope* nextScope;
Backend& backend;
const ScopeType scopeType;
bool activated = false;
};

} // namespace mbgl
7 changes: 0 additions & 7 deletions platform/android/src/native_map_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ gl::ProcAddress NativeMapView::initializeExtension(const char* name) {
}

void NativeMapView::activate() {
if (active++) {
return;
}

oldDisplay = eglGetCurrentDisplay();
oldReadSurface = eglGetCurrentSurface(EGL_READ);
Expand Down Expand Up @@ -151,10 +148,6 @@ void NativeMapView::activate() {
* From mbgl::Backend.
*/
void NativeMapView::deactivate() {
if (--active) {
return;
}

assert(vm != nullptr);

if (oldContext != context && oldContext != EGL_NO_CONTEXT) {
Expand Down
2 changes: 0 additions & 2 deletions platform/android/src/native_map_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,6 @@ class NativeMapView : public View, public Backend {
std::shared_ptr<mbgl::ThreadPool> threadPool;
std::unique_ptr<mbgl::Map> map;
mbgl::EdgeInsets insets;

unsigned active = 0;
};

} // namespace android
Expand Down
35 changes: 27 additions & 8 deletions src/mbgl/map/backend_scope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,49 @@ BackendScope::BackendScope(Backend& backend_, ScopeType scopeType_)
if (priorScope) {
assert(priorScope->nextScope == nullptr);
priorScope->nextScope = this;
priorScope->deactivate();
}
if (scopeType == ScopeType::Explicit) {
backend.activate();
}

activate();

currentScope.set(this);
}

BackendScope::~BackendScope() {
assert(nextScope == nullptr);
deactivate();

if (priorScope) {
priorScope->backend.activate();
priorScope->activate();
currentScope.set(priorScope);
assert(priorScope->nextScope == this);
priorScope->nextScope = nullptr;
} else {
if (scopeType == ScopeType::Explicit) {
backend.deactivate();
}

currentScope.set(nullptr);
}
}

void BackendScope::activate() {
if (scopeType == ScopeType::Explicit &&
!(priorScope && this->backend == priorScope->backend) &&
!(nextScope && this->backend == nextScope->backend)) {
// Only activate when set to Explicit and
// only once per RenderBackend
backend.activate();
activated = true;
}
}

void BackendScope::deactivate() {
if (activated &&
!(nextScope && this->backend == nextScope->backend)) {
// Only deactivate when set to Explicit and
// only once per RenderBackend
backend.deactivate();
activated = false;
}
}

bool BackendScope::exists() {
return currentScope.get();
}
Expand Down
113 changes: 113 additions & 0 deletions test/renderer/backend_scope.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include <mbgl/test/util.hpp>

#include <mbgl/map/backend.hpp>
#include <mbgl/map/backend_scope.hpp>

#include <functional>

using namespace mbgl;

class StubBackend: public Backend {
public:

void activate() override {
if (activateFunction) activateFunction();
}

void deactivate() override {
if (deactivateFunction) deactivateFunction();
}

void updateAssumedState() override {
if (updateAssumedStateFunction) updateAssumedStateFunction();
}

void invalidate() override {}

gl::ProcAddress initializeExtension(const char* ext) override {
if (initializeExtensionFunction) {
return initializeExtensionFunction(ext);
} else {
return {};
}
}

std::function<void ()> activateFunction;
std::function<void ()> deactivateFunction;
std::function<void ()> updateAssumedStateFunction;
std::function<gl::ProcAddress (const char*)> initializeExtensionFunction;
};

// A scope should activate on construction
// and deactivate on descruction (going out
// of scope)
TEST(BackendScope, SingleScope) {
bool activated;
bool deactivated;

StubBackend backend;
backend.activateFunction = [&] { activated = true; };
backend.deactivateFunction = [&] { deactivated = true; };

{
BackendScope test { backend };
}

ASSERT_TRUE(activated);
ASSERT_TRUE(deactivated);
}

// With nested scopes, only the outer scope
// should activate/deactivate
TEST(BackendScope, NestedScopes) {
int activated = 0;
int deactivated = 0;

StubBackend backend;
backend.activateFunction = [&] { activated++; };
backend.deactivateFunction = [&] { deactivated++; };

{
BackendScope outer { backend };
ASSERT_EQ(1, activated);
{
BackendScope inner { backend };
ASSERT_EQ(1, activated);
}
ASSERT_EQ(0, deactivated);
}

ASSERT_EQ(1, deactivated);
}

// With chained scopes, where scopes have
// different backends, the scopes should each
// activate the scope on entering and de-activating
// on leaving the scope
TEST(BackendScope, ChainedScopes) {
bool activatedA = false;
bool activatedB = false;

StubBackend backendA;
backendA.activateFunction = [&] { activatedA = true; };
backendA.deactivateFunction = [&] { activatedA = false; };

StubBackend backendB;
backendB.activateFunction = [&] { activatedB = true; };
backendB.deactivateFunction = [&] { activatedB = false; };

{
BackendScope scopeA { backendA };
ASSERT_TRUE(activatedA);
{
BackendScope scopeB { backendB };
ASSERT_FALSE(activatedA);
ASSERT_TRUE(activatedB);
}
ASSERT_FALSE(activatedB);
ASSERT_TRUE(activatedA);
}

ASSERT_FALSE(activatedA);
ASSERT_FALSE(activatedB);
}