Add unit tests for LayerComposer
This commit is contained in:
parent
dbbb8ab795
commit
128cc2422d
11 changed files with 298 additions and 19 deletions
|
|
@ -118,6 +118,7 @@ set(SOURCES
|
||||||
anbox/graphics/layer_composer.cpp
|
anbox/graphics/layer_composer.cpp
|
||||||
anbox/graphics/program_family.cpp
|
anbox/graphics/program_family.cpp
|
||||||
anbox/graphics/primitives.h
|
anbox/graphics/primitives.h
|
||||||
|
anbox/graphics/renderer.h
|
||||||
|
|
||||||
anbox/graphics/emugl/ColorBuffer.cpp
|
anbox/graphics/emugl/ColorBuffer.cpp
|
||||||
anbox/graphics/emugl/DisplayManager.cpp
|
anbox/graphics/emugl/DisplayManager.cpp
|
||||||
|
|
|
||||||
|
|
@ -47,3 +47,9 @@ void Renderable::set_screen_position(
|
||||||
const anbox::graphics::Rect &screen_position) {
|
const anbox::graphics::Rect &screen_position) {
|
||||||
screen_position_ = screen_position;
|
screen_position_ = screen_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Renderable &r) {
|
||||||
|
return out << "{ name " << r.name() << " buffer " << r.buffer()
|
||||||
|
<< " screen position " << r.screen_position() << " crop "
|
||||||
|
<< r.crop() << " alpha " << r.alpha();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,16 @@ class Renderable {
|
||||||
|
|
||||||
void set_screen_position(const anbox::graphics::Rect &screen_position);
|
void set_screen_position(const anbox::graphics::Rect &screen_position);
|
||||||
|
|
||||||
|
inline bool operator==(const Renderable &rhs) const {
|
||||||
|
return (name_ == rhs.name() && buffer_ == rhs.buffer() &&
|
||||||
|
screen_position_ == rhs.screen_position() && crop_ == rhs.crop() &&
|
||||||
|
transformation_ == rhs.transformation() && alpha_ == rhs.alpha());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const Renderable &rhs) const {
|
||||||
|
return !operator==(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
std::uint32_t buffer_;
|
std::uint32_t buffer_;
|
||||||
|
|
@ -52,6 +62,8 @@ class Renderable {
|
||||||
float alpha_;
|
float alpha_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const Renderable &r);
|
||||||
|
|
||||||
typedef std::vector<Renderable> RenderableList;
|
typedef std::vector<Renderable> RenderableList;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "anbox/graphics/primitives.h"
|
#include "anbox/graphics/primitives.h"
|
||||||
#include "anbox/graphics/program_family.h"
|
#include "anbox/graphics/program_family.h"
|
||||||
|
#include "anbox/graphics/renderer.h"
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
|
@ -71,10 +72,10 @@ struct RendererWindow;
|
||||||
// There is only one global instance, that can be retrieved with getFB(),
|
// There is only one global instance, that can be retrieved with getFB(),
|
||||||
// and which must be previously setup by calling initialize().
|
// and which must be previously setup by calling initialize().
|
||||||
//
|
//
|
||||||
class Renderer {
|
class Renderer : public anbox::graphics::Renderer {
|
||||||
public:
|
public:
|
||||||
Renderer();
|
Renderer();
|
||||||
~Renderer();
|
virtual ~Renderer();
|
||||||
|
|
||||||
// Initialize the global instance.
|
// Initialize the global instance.
|
||||||
// |width| and |height| are the dimensions of the emulator GPU display
|
// |width| and |height| are the dimensions of the emulator GPU display
|
||||||
|
|
@ -223,7 +224,7 @@ class Renderer {
|
||||||
|
|
||||||
bool draw(EGLNativeWindowType native_window,
|
bool draw(EGLNativeWindowType native_window,
|
||||||
const anbox::graphics::Rect& window_frame,
|
const anbox::graphics::Rect& window_frame,
|
||||||
const RenderableList& renderables);
|
const RenderableList& renderables) override;
|
||||||
|
|
||||||
// Return the host EGLDisplay used by this instance.
|
// Return the host EGLDisplay used by this instance.
|
||||||
EGLDisplay getDisplay() const { return m_eglDisplay; }
|
EGLDisplay getDisplay() const { return m_eglDisplay; }
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,9 @@ void logger_write(const char *format, ...) {
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace graphics {
|
namespace graphics {
|
||||||
GLRendererServer::GLRendererServer(const std::shared_ptr<wm::Manager> &wm)
|
GLRendererServer::GLRendererServer(const std::shared_ptr<wm::Manager> &wm)
|
||||||
: renderer_(std::make_shared<Renderer>()),
|
: renderer_(std::make_shared<::Renderer>()),
|
||||||
wm_(wm),
|
wm_(wm),
|
||||||
composer_(std::make_shared<LayerComposer>(renderer_, wm)) {
|
composer_(std::make_shared<LayerComposer>(renderer_, wm)) {
|
||||||
|
|
||||||
if (utils::is_env_set("USE_HOST_GLES")) {
|
if (utils::is_env_set("USE_HOST_GLES")) {
|
||||||
// Force the host EGL/GLES libraries as translator implementation
|
// Force the host EGL/GLES libraries as translator implementation
|
||||||
::setenv("ANDROID_EGL_LIB", "libEGL.so.1", 0);
|
::setenv("ANDROID_EGL_LIB", "libEGL.so.1", 0);
|
||||||
|
|
@ -83,8 +82,6 @@ GLRendererServer::GLRendererServer(const std::shared_ptr<wm::Manager> &wm)
|
||||||
registerLayerComposer(composer_);
|
registerLayerComposer(composer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLRendererServer::~GLRendererServer() {
|
GLRendererServer::~GLRendererServer() { renderer_->finalize(); }
|
||||||
renderer_->finalize();
|
|
||||||
}
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
} // namespace anbox
|
} // namespace anbox
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace graphics {
|
namespace graphics {
|
||||||
LayerComposer::LayerComposer(const std::shared_ptr<Renderer> renderer, const std::shared_ptr<wm::Manager> &wm)
|
LayerComposer::LayerComposer(const std::shared_ptr<Renderer> renderer,
|
||||||
|
const std::shared_ptr<wm::Manager> &wm)
|
||||||
: renderer_(renderer), wm_(wm) {}
|
: renderer_(renderer), wm_(wm) {}
|
||||||
|
|
||||||
LayerComposer::~LayerComposer() {}
|
LayerComposer::~LayerComposer() {}
|
||||||
|
|
@ -85,10 +86,9 @@ void LayerComposer::submit_layers(const RenderableList &renderables) {
|
||||||
final_renderables.push_back(new_renderable);
|
final_renderables.push_back(new_renderable);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer_->draw(
|
renderer_->draw(window->native_handle(), Rect{0, 0, window->frame().width(),
|
||||||
window->native_handle(),
|
window->frame().height()},
|
||||||
Rect{0, 0, window->frame().width(), window->frame().height()},
|
final_renderables);
|
||||||
final_renderables);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,10 @@
|
||||||
#ifndef ANBOX_GRAPHICS_LAYER_COMPOSER_H_
|
#ifndef ANBOX_GRAPHICS_LAYER_COMPOSER_H_
|
||||||
#define ANBOX_GRAPHICS_LAYER_COMPOSER_H_
|
#define ANBOX_GRAPHICS_LAYER_COMPOSER_H_
|
||||||
|
|
||||||
#include "anbox/graphics/emugl/Renderable.h"
|
#include "anbox/graphics/renderer.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class Renderer;
|
|
||||||
|
|
||||||
namespace anbox {
|
namespace anbox {
|
||||||
namespace wm {
|
namespace wm {
|
||||||
class Manager;
|
class Manager;
|
||||||
|
|
@ -31,7 +29,8 @@ class Manager;
|
||||||
namespace graphics {
|
namespace graphics {
|
||||||
class LayerComposer {
|
class LayerComposer {
|
||||||
public:
|
public:
|
||||||
LayerComposer(const std::shared_ptr<Renderer> renderer, const std::shared_ptr<wm::Manager> &wm);
|
LayerComposer(const std::shared_ptr<Renderer> renderer,
|
||||||
|
const std::shared_ptr<wm::Manager> &wm);
|
||||||
~LayerComposer();
|
~LayerComposer();
|
||||||
|
|
||||||
void submit_layers(const RenderableList &renderables);
|
void submit_layers(const RenderableList &renderables);
|
||||||
|
|
|
||||||
38
src/anbox/graphics/renderer.h
Normal file
38
src/anbox/graphics/renderer.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 3, as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||||
|
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANBOX_GRAPHICS_RENDERER_H_
|
||||||
|
#define ANBOX_GRAPHICS_RENDERER_H_
|
||||||
|
|
||||||
|
#include "anbox/graphics/emugl/Renderable.h"
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
namespace anbox {
|
||||||
|
namespace graphics {
|
||||||
|
class Renderer {
|
||||||
|
public:
|
||||||
|
virtual ~Renderer() {}
|
||||||
|
|
||||||
|
virtual bool draw(EGLNativeWindowType native_window,
|
||||||
|
const anbox::graphics::Rect& window_frame,
|
||||||
|
const RenderableList& renderables) = 0;
|
||||||
|
};
|
||||||
|
} // namespace graphics
|
||||||
|
} // namespace anbox
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -24,7 +24,7 @@ class NullWindow : public anbox::wm::Window {
|
||||||
public:
|
public:
|
||||||
NullWindow(const anbox::wm::Task::Id &task,
|
NullWindow(const anbox::wm::Task::Id &task,
|
||||||
const anbox::graphics::Rect &frame)
|
const anbox::graphics::Rect &frame)
|
||||||
: anbox::wm::Window(nullptr, 0, frame) {}
|
: anbox::wm::Window(nullptr, task, frame) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,7 +34,6 @@ DefaultPlatformPolicy::DefaultPlatformPolicy() {}
|
||||||
|
|
||||||
std::shared_ptr<Window> DefaultPlatformPolicy::create_window(
|
std::shared_ptr<Window> DefaultPlatformPolicy::create_window(
|
||||||
const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) {
|
const anbox::wm::Task::Id &task, const anbox::graphics::Rect &frame) {
|
||||||
DEBUG("");
|
|
||||||
return std::make_shared<::NullWindow>(task, frame);
|
return std::make_shared<::NullWindow>(task, frame);
|
||||||
}
|
}
|
||||||
} // namespace wm
|
} // namespace wm
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
ANBOX_ADD_TEST(buffer_queue_tests buffer_queue_tests.cpp)
|
ANBOX_ADD_TEST(buffer_queue_tests buffer_queue_tests.cpp)
|
||||||
ANBOX_ADD_TEST(buffered_io_stream_tests buffered_io_stream_tests.cpp)
|
ANBOX_ADD_TEST(buffered_io_stream_tests buffered_io_stream_tests.cpp)
|
||||||
|
ANBOX_ADD_TEST(layer_composer_tests layer_composer_tests.cpp)
|
||||||
|
|
|
||||||
225
tests/anbox/graphics/layer_composer_tests.cpp
Normal file
225
tests/anbox/graphics/layer_composer_tests.cpp
Normal file
|
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 3, as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranties of
|
||||||
|
* MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Both includes need to go first as otherwise they can conflict with EGL.h
|
||||||
|
// being included by the following includes.
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "anbox/wm/default_platform_policy.h"
|
||||||
|
#include "anbox/wm/manager.h"
|
||||||
|
#include "anbox/wm/window_state.h"
|
||||||
|
|
||||||
|
#include "anbox/graphics/layer_composer.h"
|
||||||
|
|
||||||
|
using namespace ::testing;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class MockRenderer : public anbox::graphics::Renderer {
|
||||||
|
public:
|
||||||
|
MOCK_METHOD3(draw, bool(EGLNativeWindowType, const anbox::graphics::Rect&,
|
||||||
|
const RenderableList&));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace anbox {
|
||||||
|
namespace graphics {
|
||||||
|
TEST(LayerComposer, FindsNoSuitableWindowForLayer) {
|
||||||
|
auto renderer = std::make_shared<MockRenderer>();
|
||||||
|
|
||||||
|
// The default policy will create a dumb window instance when requested
|
||||||
|
// from the manager.
|
||||||
|
auto platform_policy = std::make_shared<wm::DefaultPlatformPolicy>();
|
||||||
|
auto wm = std::make_shared<wm::Manager>(platform_policy);
|
||||||
|
|
||||||
|
auto single_window = wm::WindowState{
|
||||||
|
wm::Display::Id{1},
|
||||||
|
true,
|
||||||
|
graphics::Rect{0, 0, 1024, 768},
|
||||||
|
"org.anbox.test.1",
|
||||||
|
wm::Task::Id{1},
|
||||||
|
wm::Stack::Freeform,
|
||||||
|
};
|
||||||
|
|
||||||
|
wm->apply_window_state_update({single_window}, {});
|
||||||
|
|
||||||
|
LayerComposer composer(renderer, wm);
|
||||||
|
|
||||||
|
// A single renderable which has a different task id then the window we know
|
||||||
|
// about
|
||||||
|
RenderableList renderables = {
|
||||||
|
{"org.anbox.surface.2", 0, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
};
|
||||||
|
|
||||||
|
// The renderer should not be called for a layer which doesn't exist
|
||||||
|
EXPECT_CALL(*renderer, draw(_, _, _)).Times(0);
|
||||||
|
|
||||||
|
composer.submit_layers(renderables);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LayerComposer, MapsLayersToWindows) {
|
||||||
|
auto renderer = std::make_shared<MockRenderer>();
|
||||||
|
|
||||||
|
// The default policy will create a dumb window instance when requested
|
||||||
|
// from the manager.
|
||||||
|
auto platform_policy = std::make_shared<wm::DefaultPlatformPolicy>();
|
||||||
|
auto wm = std::make_shared<wm::Manager>(platform_policy);
|
||||||
|
|
||||||
|
auto first_window = wm::WindowState{
|
||||||
|
wm::Display::Id{1},
|
||||||
|
true,
|
||||||
|
graphics::Rect{0, 0, 1024, 768},
|
||||||
|
"org.anbox.foo",
|
||||||
|
wm::Task::Id{1},
|
||||||
|
wm::Stack::Freeform,
|
||||||
|
};
|
||||||
|
|
||||||
|
auto second_window = wm::WindowState{
|
||||||
|
wm::Display::Id{1},
|
||||||
|
true,
|
||||||
|
graphics::Rect{300, 400, 1324, 1168},
|
||||||
|
"org.anbox.bar",
|
||||||
|
wm::Task::Id{2},
|
||||||
|
wm::Stack::Freeform,
|
||||||
|
};
|
||||||
|
|
||||||
|
wm->apply_window_state_update({first_window, second_window}, {});
|
||||||
|
|
||||||
|
LayerComposer composer(renderer, wm);
|
||||||
|
|
||||||
|
// A single renderable which has a different task id then the window we know
|
||||||
|
// about
|
||||||
|
RenderableList renderables = {
|
||||||
|
{"org.anbox.surface.1", 0, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
{"org.anbox.surface.2", 1, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderableList first_window_renderables{
|
||||||
|
{"org.anbox.surface.1", 0, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderableList second_window_renderables{
|
||||||
|
{"org.anbox.surface.2", 1, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_CALL(*renderer, draw(_, Rect{0, 0, first_window.frame().width(),
|
||||||
|
first_window.frame().height()},
|
||||||
|
first_window_renderables))
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
EXPECT_CALL(*renderer, draw(_, Rect{0, 0, second_window.frame().width(),
|
||||||
|
second_window.frame().height()},
|
||||||
|
second_window_renderables))
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
composer.submit_layers(renderables);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LayerComposer, WindowPartiallyOffscreen) {
|
||||||
|
auto renderer = std::make_shared<MockRenderer>();
|
||||||
|
|
||||||
|
// The default policy will create a dumb window instance when requested
|
||||||
|
// from the manager.
|
||||||
|
auto platform_policy = std::make_shared<wm::DefaultPlatformPolicy>();
|
||||||
|
auto wm = std::make_shared<wm::Manager>(platform_policy);
|
||||||
|
|
||||||
|
auto window = wm::WindowState{
|
||||||
|
wm::Display::Id{1},
|
||||||
|
true,
|
||||||
|
graphics::Rect{-100, -100, 924, 668},
|
||||||
|
"org.anbox.foo",
|
||||||
|
wm::Task::Id{1},
|
||||||
|
wm::Stack::Freeform,
|
||||||
|
};
|
||||||
|
|
||||||
|
wm->apply_window_state_update({window}, {});
|
||||||
|
|
||||||
|
LayerComposer composer(renderer, wm);
|
||||||
|
|
||||||
|
// Window is build out of two layers where one is placed inside the other
|
||||||
|
// but the layer covering the whole window is placed with its top left
|
||||||
|
// origin outside of the visible display area.
|
||||||
|
RenderableList renderables = {
|
||||||
|
{"org.anbox.surface.1", 0, {-100, -100, 924, 668}, {0, 0, 1024, 768}},
|
||||||
|
{"org.anbox.surface.1", 1, {0, 0, 100, 200}, {0, 0, 100, 200}},
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderableList expected_renderables{
|
||||||
|
{"org.anbox.surface.1", 0, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
{"org.anbox.surface.1", 1, {100, 100, 200, 300}, {0, 0, 100, 200}},
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
|
||||||
|
window.frame().width(),
|
||||||
|
window.frame().height()},
|
||||||
|
expected_renderables))
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
composer.submit_layers(renderables);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LayerComposer, PopupShouldNotCauseWindowLayerOffset) {
|
||||||
|
auto renderer = std::make_shared<MockRenderer>();
|
||||||
|
|
||||||
|
// The default policy will create a dumb window instance when requested
|
||||||
|
// from the manager.
|
||||||
|
auto platform_policy = std::make_shared<wm::DefaultPlatformPolicy>();
|
||||||
|
auto wm = std::make_shared<wm::Manager>(platform_policy);
|
||||||
|
|
||||||
|
auto window = wm::WindowState{
|
||||||
|
wm::Display::Id{1},
|
||||||
|
true,
|
||||||
|
graphics::Rect{1120, 270, 2144, 1038},
|
||||||
|
"org.anbox.foo",
|
||||||
|
wm::Task::Id{3},
|
||||||
|
wm::Stack::Freeform,
|
||||||
|
};
|
||||||
|
|
||||||
|
wm->apply_window_state_update({window}, {});
|
||||||
|
|
||||||
|
LayerComposer composer(renderer, wm);
|
||||||
|
|
||||||
|
// Having two renderables where the second smaller one overlaps the bigger
|
||||||
|
// one and goes a bit offscreen. This should be still placed correctly and
|
||||||
|
// the small layer should go offscreen as it is supposed to. This typically
|
||||||
|
// happens when a popup window appears which has a shadow attached which goes
|
||||||
|
// out of the window area. In our case this is not possible as the area the
|
||||||
|
// window has available is static.
|
||||||
|
RenderableList renderables = {
|
||||||
|
{"org.anbox.surface.3", 0, {1120,270,2144,1038}, {0, 0, 1024, 768}},
|
||||||
|
{"org.anbox.surface.3", 1, {1904, 246, 2164, 406}, {0, 0, 260, 160}},
|
||||||
|
};
|
||||||
|
|
||||||
|
RenderableList expected_renderables{
|
||||||
|
{"org.anbox.surface.3", 0, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
|
||||||
|
{"org.anbox.surface.3", 1, {784, -24, 1044, 136}, {0, 0, 260, 160}},
|
||||||
|
};
|
||||||
|
|
||||||
|
EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
|
||||||
|
window.frame().width(),
|
||||||
|
window.frame().height()},
|
||||||
|
expected_renderables))
|
||||||
|
.Times(1)
|
||||||
|
.WillOnce(Return(true));
|
||||||
|
|
||||||
|
composer.submit_layers(renderables);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace graphics
|
||||||
|
} // namespace anbox
|
||||||
Loading…
Add table
Add a link
Reference in a new issue