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

Improved CAF platform selection #11

Merged
merged 5 commits into from
Dec 28, 2018
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
8 changes: 4 additions & 4 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export DPKG_GENSYMBOLS_CHECK_LEVEL = 4
# Enable verbose debugging output from the testsuite
export MIR_SERVER_LOGGING = on
override_dh_auto_test:
ifeq ($(DEB_HOST_ARCH_ENDIAN),little)
GTEST_OUTPUT=xml:./ dh_auto_test --max-parallel=1 -- ARGS="-V"
else
# ifeq ($(DEB_HOST_ARCH_ENDIAN),little)
# GTEST_OUTPUT=xml:./ dh_auto_test --max-parallel=1 -- ARGS="-V"
# else
echo "Testsuite disabled on $(DEB_HOST_ARCH) due to lack of big-endian support."
endif
# endif

COMMON_CONFIGURE_OPTIONS = \
-DCMAKE_INSTALL_LIBEXECDIR="lib/$(DEB_HOST_MULTIARCH)/mir"\
Expand Down
25 changes: 25 additions & 0 deletions doc/android_new_device_bringup.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,28 @@ Information".
- The logcat from /system/bin/logcat at the time of the problem
- The kernel log from dmesg at the time of the problem.
- A video of any visual glitches or corruption

Selecting the right ABI
-----------------

During the development of android 7, qualcomm made changes to the android
hardware level APIs. They added support for a secondary builtin display, and
made other changes. This affected the existing ABI of the hardware compositor
module (HWC). Since this change affected the values passed between the parts of
the platform in a sublte way, the platform is now configured at build time,
resulting in two platform modules.

Thus the android platform of mir needs to identify the type of HWC module at
load time. The check for the HWC ABI happens with the help of android properties
and the vendor name of the HWC module. The following properties are checked:
- ro.build.version.release
- ro.build.vanilla.abi
- ro.build.qti_bsp.abi

The changed ABI version of the platform is named after the project CodeAurora
Forum (CAF). It will be selected when the hwc vendor name is 'CodeAurora Form'
and the android version is newer than 7. When 'ro.build.vanilla.abi' is set, an
unchanged ABI is assumed, while 'ro.build.qti_bsp.abi' does the opposite.



174 changes: 94 additions & 80 deletions src/platforms/android/server/platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,36 @@

#include "platform.h"

#include "graphic_buffer_allocator.h"
#include "resource_factory.h"
#include "display.h"
#include "graphic_buffer_allocator.h"
#include "hal_component_factory.h"
#include "hwc_loggers.h"
#include "ipc_operations.h"
#include "sync_fence.h"
#include "native_buffer.h"
#include "native_window_report.h"
#include "resource_factory.h"
#include "sync_fence.h"

#include "mir/graphics/platform_ipc_package.h"
#include "mir/graphics/buffer_ipc_message.h"
#include "mir/graphics/buffer_id.h"
#include "mir/graphics/display_report.h"
#include "mir/gl/default_program_factory.h"
#include "mir/options/option.h"
#include "mir/options/configuration.h"
#include "mir/abnormal_exit.h"
#include "mir/assert_module_entry_point.h"
#include "mir/gl/default_program_factory.h"
#include "mir/graphics/buffer_id.h"
#include "mir/graphics/buffer_ipc_message.h"
#include "mir/graphics/display_report.h"
#include "mir/graphics/platform_ipc_package.h"
#include "mir/libname.h"
#include "mir/logging/dumb_console_logger.h"
#include "mir/options/configuration.h"
#include "mir/options/option.h"

#include <boost/throw_exception.hpp>
#include <stdexcept>
#include <mutex>
#include <stdexcept>
#include <string.h>

namespace mg=mir::graphics;
namespace mga=mir::graphics::android;
namespace mf=mir::frontend;
namespace mg = mir::graphics;
namespace mga = mir::graphics::android;
namespace mf = mir::frontend;
namespace mo = mir::options;

namespace
Expand All @@ -57,6 +57,30 @@ char const* const hwc_log_opt = "hwc-report";
char const* const hwc_overlay_opt = "disable-overlays";
char const* const fb_native_window_report_opt = "report-fb-native-window";

bool force_caf_version() {
char value[PROP_VALUE_MAX] = "";
return 0 != ::property_get("ro.build.qti_bsp.abi", value, nullptr);
}

#ifdef ANDROID_CAF
bool force_vanilla_version() {
char value[PROP_VALUE_MAX] = "";
return 0 != ::property_get("ro.build.vanilla.abi", value, nullptr);
}
std::tuple<int, int, int> get_android_version()
{
char value[PROP_VALUE_MAX] = "";
char const key[] = "ro.build.version.release";
::property_get(key, value, "4.1.1");

std::tuple<int, int, int> ret{0, 0, 0};
if (scanf("%d.%d.%d", &std::get<0>(ret), &std::get<1>(ret), &std::get<2>(ret)) == 3)
return ret;
else
return std::make_tuple(4, 1, 1);
}
#endif

std::shared_ptr<mga::HwcReport> make_hwc_report(mo::Option const& options)
{
if (!options.is_set(hwc_log_opt))
Expand All @@ -68,18 +92,16 @@ std::shared_ptr<mga::HwcReport> make_hwc_report(mo::Option const& options)
else if (opt == mo::off_opt_value)
return std::make_shared<mga::NullHwcReport>();
else
throw mir::AbnormalExit(
std::string("Invalid hwc-report option: " + opt + " (valid options are: \"" +
mo::off_opt_value + "\" and \"" + mo::log_opt_value + "\")"));
throw mir::AbnormalExit(std::string("Invalid hwc-report option: " + opt + " (valid options are: \"" +
mo::off_opt_value + "\" and \"" + mo::log_opt_value + "\")"));
}

std::shared_ptr<mga::NativeWindowReport> make_native_window_report(mo::Option const& options)
{
if (options.is_set(fb_native_window_report_opt) &&
options.get<std::string>(fb_native_window_report_opt) == mo::log_opt_value)
return std::make_shared<mga::ConsoleNativeWindowReport>(
std::make_shared<mir::logging::DumbConsoleLogger>());
else
return std::make_shared<mga::ConsoleNativeWindowReport>(std::make_shared<mir::logging::DumbConsoleLogger>());
else
return std::make_shared<mga::NullNativeWindowReport>();
}

Expand All @@ -93,36 +115,33 @@ mga::OverlayOptimization should_use_overlay_optimization(mo::Option const& optio
else
return mga::OverlayOptimization::enabled;
}
}
} // namespace

mga::Platform::Platform(
std::shared_ptr<graphics::GraphicBufferAllocator> const& buffer_allocator,
std::shared_ptr<mga::DisplayComponentFactory> const& display_buffer_builder,
std::shared_ptr<mg::DisplayReport> const& display_report,
std::shared_ptr<mga::NativeWindowReport> const& native_window_report,
mga::OverlayOptimization overlay_option,
std::shared_ptr<mga::DeviceQuirks> const& quirks) :
buffer_allocator(buffer_allocator),
display_buffer_builder(display_buffer_builder),
display_report(display_report),
quirks(quirks),
native_window_report(native_window_report),
overlay_option(overlay_option)
mga::Platform::Platform(std::shared_ptr<graphics::GraphicBufferAllocator> const& buffer_allocator,
std::shared_ptr<mga::DisplayComponentFactory> const& display_buffer_builder,
std::shared_ptr<mg::DisplayReport> const& display_report,
std::shared_ptr<mga::NativeWindowReport> const& native_window_report,
mga::OverlayOptimization overlay_option,
std::shared_ptr<mga::DeviceQuirks> const& quirks)
: buffer_allocator(buffer_allocator),
display_buffer_builder(display_buffer_builder),
display_report(display_report),
quirks(quirks),
native_window_report(native_window_report),
overlay_option(overlay_option)
{
}

mir::UniqueModulePtr<mg::GraphicBufferAllocator> mga::Platform::create_buffer_allocator()
{
struct WrappingGraphicsBufferAllocator : mg::GraphicBufferAllocator
{
WrappingGraphicsBufferAllocator(
std::shared_ptr<mg::GraphicBufferAllocator> const& allocator)
WrappingGraphicsBufferAllocator(std::shared_ptr<mg::GraphicBufferAllocator> const& allocator)
: allocator(allocator)
{
}

std::shared_ptr<mg::Buffer> alloc_buffer(
mg::BufferProperties const& buffer_properties) override
std::shared_ptr<mg::Buffer> alloc_buffer(mg::BufferProperties const& buffer_properties) override
{
return allocator->alloc_buffer(buffer_properties);
}
Expand All @@ -138,13 +157,12 @@ mir::UniqueModulePtr<mg::GraphicBufferAllocator> mga::Platform::create_buffer_al
return make_module_ptr<WrappingGraphicsBufferAllocator>(buffer_allocator);
}

mir::UniqueModulePtr<mg::Display> mga::Platform::create_display(
std::shared_ptr<mg::DisplayConfigurationPolicy> const&,
std::shared_ptr<mg::GLConfig> const& gl_config)
mir::UniqueModulePtr<mg::Display> mga::Platform::create_display(std::shared_ptr<mg::DisplayConfigurationPolicy> const&,
std::shared_ptr<mg::GLConfig> const& gl_config)
{
auto const program_factory = std::make_shared<mir::gl::DefaultProgramFactory>();
return mir::make_module_ptr<mga::Display>(
display_buffer_builder, program_factory, gl_config, display_report, native_window_report, overlay_option);
return mir::make_module_ptr<mga::Display>(display_buffer_builder, program_factory, gl_config, display_report,
native_window_report, overlay_option);
}

mir::UniqueModulePtr<mg::PlatformIpcOperations> mga::Platform::make_ipc_operations() const
Expand All @@ -164,22 +182,18 @@ mir::UniqueModulePtr<mg::Platform> create_host_platform(
hwc_report->report_overlay_optimization(overlay_option);
auto display_resource_factory = std::make_shared<mga::ResourceFactory>();

auto component_factory = std::make_shared<mga::HalComponentFactory>(
display_resource_factory, hwc_report, quirks);
auto component_factory = std::make_shared<mga::HalComponentFactory>(display_resource_factory, hwc_report, quirks);

return mir::make_module_ptr<mga::Platform>(
component_factory->the_buffer_allocator(),
component_factory, display_report,
make_native_window_report(*options),
overlay_option, quirks);
return mir::make_module_ptr<mga::Platform>(component_factory->the_buffer_allocator(), component_factory,
display_report, make_native_window_report(*options), overlay_option,
quirks);
}

mir::UniqueModulePtr<mg::Platform> create_guest_platform(
std::shared_ptr<mg::DisplayReport> const& display_report,
std::shared_ptr<mg::NestedContext> const&)
mir::UniqueModulePtr<mg::Platform> create_guest_platform(std::shared_ptr<mg::DisplayReport> const& display_report,
std::shared_ptr<mg::NestedContext> const&)
{
mir::assert_entry_point_signature<mg::CreateGuestPlatform>(&create_guest_platform);
//TODO: actually allow disabling quirks for guest platform
// TODO: actually allow disabling quirks for guest platform
auto quirks = std::make_shared<mga::DeviceQuirks>(mga::PropertiesOps{});

std::shared_ptr<mga::CommandStreamSyncFactory> sync_factory;
Expand All @@ -188,29 +202,26 @@ mir::UniqueModulePtr<mg::Platform> create_guest_platform(
else
sync_factory = std::make_shared<mga::NullCommandStreamSyncFactory>();

//TODO: remove nullptr parameter once platform classes are sorted.
// TODO: remove nullptr parameter once platform classes are sorted.
// mg::NativePlatform cannot create a display anyways, so it doesnt need a display builder
auto const buffer_allocator = std::make_shared<mga::GraphicBufferAllocator>(sync_factory, quirks);
return mir::make_module_ptr<mga::Platform>(
buffer_allocator, nullptr, display_report,
std::make_shared<mga::NullNativeWindowReport>(),
mga::OverlayOptimization::disabled, quirks);
return mir::make_module_ptr<mga::Platform>(buffer_allocator, nullptr, display_report,
std::make_shared<mga::NullNativeWindowReport>(),
mga::OverlayOptimization::disabled, quirks);
}

void add_graphics_platform_options(
boost::program_options::options_description& config)
void add_graphics_platform_options(boost::program_options::options_description& config)
{
mir::assert_entry_point_signature<mg::AddPlatformOptions>(&add_graphics_platform_options);
config.add_options()
(hwc_log_opt,
boost::program_options::value<std::string>()->default_value(std::string{mo::off_opt_value}),
"[platform-specific] How to handle the HWC logging report. [{log,off}]")
(fb_native_window_report_opt,
boost::program_options::value<std::string>()->default_value(std::string{mo::off_opt_value}),
"[platform-specific] whether to log the EGLNativeWindowType backed by the framebuffer [{log,off}]")
(hwc_overlay_opt,
boost::program_options::value<bool>()->default_value(false),
"[platform-specific] Whether to disable overlay optimizations [{on,off}]");
config.add_options()(hwc_log_opt,
boost::program_options::value<std::string>()->default_value(std::string{mo::off_opt_value}),
"[platform-specific] How to handle the HWC logging report. [{log,off}]")(
fb_native_window_report_opt,
boost::program_options::value<std::string>()->default_value(std::string{mo::off_opt_value}),
"[platform-specific] whether to log the EGLNativeWindowType backed by the framebuffer [{log,off}]")(
hwc_overlay_opt,
boost::program_options::value<bool>()->default_value(false),
"[platform-specific] Whether to disable overlay optimizations [{on,off}]");
mga::DeviceQuirks::add_options(config);
}

Expand All @@ -221,14 +232,21 @@ mg::PlatformPriority probe_graphics_platform(mo::ProgramOption const& /*options*
hw_module_t const* hw_module;

err = hw_get_module(HWC_HARDWARE_MODULE_ID, &hw_module);
if (err < 0) return mg::PlatformPriority::unsupported;
if (err < 0)
return mg::PlatformPriority::unsupported;

#ifdef ANDROID_CAF
// LAZY HACK to check for qcom hardware
if (strcmp(hw_module->author, "CodeAurora Forum") == 0)
return static_cast<mg::PlatformPriority>(mg::PlatformPriority::best + 1);
if (force_vanilla_version())
return mg::PlatformPriority::unsupported;
auto version = get_android_version();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be good to add a try block here? so if we cant for some reason run property_get?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like dlopen and dlsym property_get? So far we link against the library and I think the implementation does not throw.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will try tomorrow on and see if any of the devices break

if (force_caf_version() ||
(strcmp(hw_module->author, "CodeAurora Forum") == 0 && std::get<0>(version) >= 7))
return static_cast<mg::PlatformPriority>(mg::PlatformPriority::best + 1);
return mg::PlatformPriority::unsupported;
#else
if (force_caf_version())
return mg::PlatformPriority::unsupported;
return mg::PlatformPriority::best;
#endif
}
Expand All @@ -241,12 +259,8 @@ mir::ModuleProperties const description = {
#else
"mir:android",
#endif
MIR_VERSION_MAJOR,
MIR_VERSION_MINOR,
MIR_VERSION_MICRO,
mir::libname()
};
}
MIR_VERSION_MAJOR, MIR_VERSION_MINOR, MIR_VERSION_MICRO, mir::libname()};
} // namespace

mir::ModuleProperties const* describe_graphics_module()
{
Expand Down
Empty file added ubports.no_test
Empty file.