Commit e4c64c3d by Ian Elliott Committed by Commit Bot

Implement new API/interface for the ANGLE feature-support utility.

The original API is designated as version 0. The new API is designated as version 1. A new function is provided for determing the version of the API that can be used. Bug: angleproject:2794 Change-Id: I8205b462522cbc34d31643ea14815e187497abed Reviewed-on: https://chromium-review.googlesource.com/c/1278836Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent 2b73d625
...@@ -933,6 +933,7 @@ if (is_android) { ...@@ -933,6 +933,7 @@ if (is_android) {
libs = [ "log" ] libs = [ "log" ]
sources = [ sources = [
"src/feature_support_util/angle_feature_support_util.h",
"src/feature_support_util/feature_support_util.cpp", "src/feature_support_util/feature_support_util.cpp",
"src/feature_support_util/feature_support_util.h", "src/feature_support_util/feature_support_util.h",
] ]
......
//
// Copyright 2018 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.
//
// angle_feature_support_util.h: External header file for feature-support utilities.
// feature_support_util.cpp: Helps Android EGL loader to determine whether to
// use ANGLE or a native GLES driver. Can be extended in the future for
// more-general feature selection.
#ifndef ANGLE_FEATURE_SUPPORT_UTIL_H_
#define ANGLE_FEATURE_SUPPORT_UTIL_H_
#if defined(ANDROID)
// FIXME - NEED TO #define ANGLE_EXPORT in a way that works for Android builds
#include "export.h"
#else
#include "export.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
// The following is the "version 1" external interface that the Android EGL loader used.
// Callers of the ANGLE feature-support-utility API (e.g. the Android EGL loader) will call this
// function in order to determine what version of the API it can use (if any).
//
// The caller supplies the highest version of the API that it knows about. If that version is
// supported by the feature-support-utility, true is returned and the version isn't changed. If
// the supplied version is higher than supported by the feature-support-utility, true is returned
// and the version is changed to the highest supported by the feature-support-utility. If the
// supplied version is lower than supported by the feature-support-utility, false is returned.
//
// Parameters:
//
// - versionToUse (IN/OUT) - The application supplies the highest version of the interface that it
// knows about. If successful, the output value is either unchanged or is the highest supported
// by the interface.
//
ANGLE_EXPORT bool ANGLEGetUtilityAPI(unsigned int *versionToUse);
// The Android EGL loader will call this function in order to determine whether
// to use ANGLE instead of a native OpenGL-ES (GLES) driver.
//
// Parameters:
// - rules_fd - File descriptor of the rules file to use
// - rules_offset - Offset into the fd before finding the contents of the rules file
// - rules_length - length of the rules file content
// - appName - Java name of the application (e.g. "com.google.android.apps.maps")
// - deviceMfr - Device manufacturer, from the "ro.product.manufacturer"com.google.android" property
// - deviceModel - Device model, from the "ro.product.model"com.google.android" property
//
ANGLE_EXPORT bool AndroidUseANGLEForApplication(int rules_fd,
long rules_offset,
long rules_length,
const char *appName,
const char *deviceMfr,
const char *deviceModel);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // ANGLE_FEATURE_SUPPORT_UTIL_H_
...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// feature_support_util.cpp: Implementation of the code that helps the Android EGL loader // feature_support_util.cpp: Helps Android EGL loader to determine whether to use ANGLE or a native
// determine whether to use ANGLE or a native GLES driver. // GLES driver. Helps ANGLE know which work-arounds to use.
#include "feature_support_util.h" #include "feature_support_util.h"
#include <json/json.h> #include <json/json.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <fstream> #include <fstream>
#include <list> #include <list>
...@@ -805,29 +806,15 @@ class RuleList ...@@ -805,29 +806,15 @@ class RuleList
return answer; return answer;
} }
static RuleList *ReadRulesFromJsonFile() static RuleList *ReadRulesFromJsonString(std::string jsonFileContents)
{ {
RuleList *rules = new RuleList; RuleList *rules = new RuleList;
// Open the file and start parsing it: // Open the file and start parsing it:
using namespace std; using namespace std;
#ifdef READ_FROM_JSON_FILE
// FIXME/TODO: NEED TO GET THE FINAL LOCATION AND ENSURE THAT ANY APPLICATION CAN READ FROM
// THAT LOCATION.
ifstream ifs("/system/app/ANGLEPrebuilt/a4a_rules.json");
Json::Reader jReader;
Json::Value jTopLevelObject;
jReader.parse(ifs, jTopLevelObject);
#else // READ_FROM_JSON_FILE
// Embed the rules file contents into a string:
const char *s =
#include "a4a_rules.json"
;
std::string jsonFileContents = s;
Json::Reader jReader; Json::Reader jReader;
Json::Value jTopLevelObject; Json::Value jTopLevelObject;
jReader.parse(jsonFileContents, jTopLevelObject); jReader.parse(jsonFileContents, jTopLevelObject);
#endif // READ_FROM_JSON_FILE
Json::Value jRules = jTopLevelObject[kJsonRules]; Json::Value jRules = jTopLevelObject[kJsonRules];
for (unsigned int i = 0; i < jRules.size(); i++) for (unsigned int i = 0; i < jRules.size(); i++)
{ {
...@@ -907,9 +894,17 @@ ANGLE_EXPORT bool ANGLEUseForApplication(const char *appName, ...@@ -907,9 +894,17 @@ ANGLE_EXPORT bool ANGLEUseForApplication(const char *appName,
ANGLEPreference appPreference) ANGLEPreference appPreference)
{ {
Scenario scenario(appName, deviceMfr, deviceModel); Scenario scenario(appName, deviceMfr, deviceModel);
RuleList *rules = RuleList::ReadRulesFromJsonFile();
bool rtn = false; bool rtn = false;
scenario.logScenario(); scenario.logScenario();
// #include the contents of the file into a string and then parse it:
using namespace std;
// Embed the rules file contents into a string:
const char *s =
#include "a4a_rules.json"
;
std::string jsonFileContents = s;
RuleList *rules = RuleList::ReadRulesFromJsonString(jsonFileContents);
rules->logRules(); rules->logRules();
if (developerOption != ANGLE_NO_PREFERENCE) if (developerOption != ANGLE_NO_PREFERENCE)
...@@ -924,6 +919,70 @@ ANGLE_EXPORT bool ANGLEUseForApplication(const char *appName, ...@@ -924,6 +919,70 @@ ANGLE_EXPORT bool ANGLEUseForApplication(const char *appName,
{ {
rtn = rules->getAnswer(scenario); rtn = rules->getAnswer(scenario);
} }
ALOGV("Application \"%s\" should %s ANGLE", appName, rtn ? "use" : "NOT use");
delete rules;
return rtn;
}
ANGLE_EXPORT bool ANGLEGetUtilityAPI(unsigned int *versionToUse)
{
if (*versionToUse >= kFeatureVersion_LowestSupported)
{
if (*versionToUse <= kFeatureVersion_HighestSupported)
{
// This versionToUse is valid, and doesn't need to be changed.
return true;
}
else
{
// The versionToUse is greater than the highest version supported; change it to the
// highest version supported (caller will decide if it can use that version).
*versionToUse = kFeatureVersion_HighestSupported;
return true;
}
}
else
{
// The versionToUse is less than the lowest version supported, which is an error.
return false;
}
}
ANGLE_EXPORT bool AndroidUseANGLEForApplication(int rules_fd,
long rules_offset,
long rules_length,
const char *appName,
const char *deviceMfr,
const char *deviceModel)
{
Scenario scenario(appName, deviceMfr, deviceModel);
bool rtn = false;
scenario.logScenario();
// Read the contents of the file into a string and then parse it:
if (rules_fd < 0)
{
ALOGW("Asked to read a non-open JSON file");
return rtn;
}
off_t fileSize = rules_length;
off_t startOfContent = rules_offset;
// This is temporary magic--while there's extra stuff at the start of the file
// (so that it can be #include'd into the source code):
startOfContent += 8;
fileSize -= (8 + 7 + 2);
lseek(rules_fd, startOfContent, SEEK_SET);
char *buffer = new char[fileSize + 1];
ssize_t numBytesRead = read(rules_fd, buffer, fileSize);
buffer[numBytesRead] = '\0';
std::string jsonFileContents = std::string(buffer);
delete[] buffer;
RuleList *rules = RuleList::ReadRulesFromJsonString(jsonFileContents);
rules->logRules();
rtn = rules->getAnswer(scenario);
ALOGV("Application \"%s\" should %s ANGLE", appName, rtn ? "use" : "NOT use");
delete rules; delete rules;
return rtn; return rtn;
} }
......
...@@ -4,18 +4,25 @@ ...@@ -4,18 +4,25 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// feature_support_util.cpp: Helps Android EGL loader to determine whether to use ANGLE or a native // feature_support_util.h: Internal-to-ANGLE header file for feature-support utilities.
// GLES driver. Can be extended in the future for more-general feature selection.
#ifndef FEATURE_SUPPORT_UTIL_H_ #ifndef FEATURE_SUPPORT_UTIL_H_
#define FEATURE_SUPPORT_UTIL_H_ #define FEATURE_SUPPORT_UTIL_H_
#include "export.h" #include "angle_feature_support_util.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
// The following are internal versions supported by the current feature-support-utility API.
constexpr unsigned int kFeatureVersion_LowestSupported = 0;
constexpr unsigned int kFeatureVersion_HighestSupported = 1;
// The following is the "version 0" external interface that the Android EGL loader used. It is
// deprecated and will soon be obsoleted. It was never declared in the shared header file.
// TODO(ianelliott@google.com angleproject:2801): Revisit this enum. Make it // TODO(ianelliott@google.com angleproject:2801): Revisit this enum. Make it
// strongly typed, and look at renaming it and its values. // strongly typed, and look at renaming it and its values.
typedef enum ANGLEPreference { typedef enum ANGLEPreference {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment