Merge "Enable ANGLE-for-Android rule processing again"
diff --git a/cmds/cmd/Android.bp b/cmds/cmd/Android.bp
index d91184a..8ea71cd 100644
--- a/cmds/cmd/Android.bp
+++ b/cmds/cmd/Android.bp
@@ -1,7 +1,31 @@
+cc_library_static {
+ name: "libcmd",
+
+ srcs: ["cmd.cpp"],
+ export_include_dirs: ["."],
+
+ shared_libs: [
+ "libutils",
+ "liblog",
+ "libselinux",
+ "libbinder",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-DXP_UNIX",
+ ],
+}
+
cc_binary {
name: "cmd",
- srcs: ["cmd.cpp"],
+ srcs: ["main.cpp"],
+
+ static_libs: [
+ "libcmd",
+ ],
shared_libs: [
"libutils",
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index 0616add..7b4aeb2 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -40,6 +40,8 @@
#include "selinux/selinux.h"
#include "selinux/android.h"
+#include "cmd.h"
+
#define DEBUG 0
using namespace android;
@@ -59,8 +61,11 @@
class MyShellCallback : public BnShellCallback
{
public:
+ TextOutput& mErrorLog;
bool mActive = true;
+ MyShellCallback(TextOutput& errorLog) : mErrorLog(errorLog) {}
+
virtual int openFile(const String16& path, const String16& seLinuxContext,
const String16& mode) {
String8 path8(path);
@@ -69,7 +74,7 @@
String8 fullPath(cwd);
fullPath.appendPath(path8);
if (!mActive) {
- aerr << "Open attempt after active for: " << fullPath << endl;
+ mErrorLog << "Open attempt after active for: " << fullPath << endl;
return -EPERM;
}
#if DEBUG
@@ -78,20 +83,20 @@
int flags = 0;
bool checkRead = false;
bool checkWrite = false;
- if (mode == String16("w")) {
+ if (mode == u"w") {
flags = O_WRONLY|O_CREAT|O_TRUNC;
checkWrite = true;
- } else if (mode == String16("w+")) {
+ } else if (mode == u"w+") {
flags = O_RDWR|O_CREAT|O_TRUNC;
checkRead = checkWrite = true;
- } else if (mode == String16("r")) {
+ } else if (mode == u"r") {
flags = O_RDONLY;
checkRead = true;
- } else if (mode == String16("r+")) {
+ } else if (mode == u"r+") {
flags = O_RDWR;
checkRead = checkWrite = true;
} else {
- aerr << "Invalid mode requested: " << mode.string() << endl;
+ mErrorLog << "Invalid mode requested: " << mode.string() << endl;
return -EINVAL;
}
int fd = open(fullPath.string(), flags, S_IRWXU|S_IRWXG);
@@ -114,9 +119,7 @@
ALOGD("openFile: failed selinux write check!");
#endif
close(fd);
- aerr << "System server has no access to write file context " << context.get()
- << " (from path " << fullPath.string() << ", context "
- << seLinuxContext8.string() << ")" << endl;
+ mErrorLog << "System server has no access to write file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl;
return -EPERM;
}
}
@@ -128,9 +131,7 @@
ALOGD("openFile: failed selinux read check!");
#endif
close(fd);
- aerr << "System server has no access to read file context " << context.get()
- << " (from path " << fullPath.string() << ", context "
- << seLinuxContext8.string() << ")" << endl;
+ mErrorLog << "System server has no access to read file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl;
return -EPERM;
}
}
@@ -163,9 +164,8 @@
}
};
-int main(int argc, char* const argv[])
-{
- signal(SIGPIPE, SIG_IGN);
+int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, TextOutput& errorLog,
+ int in, int out, int err, RunMode runMode) {
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
@@ -173,68 +173,77 @@
ALOGD("cmd: starting");
#endif
sp<IServiceManager> sm = defaultServiceManager();
- fflush(stdout);
+ if (runMode == RunMode::kStandalone) {
+ fflush(stdout);
+ }
if (sm == nullptr) {
ALOGW("Unable to get default service manager!");
- aerr << "cmd: Unable to get default service manager!" << endl;
+ errorLog << "cmd: Unable to get default service manager!" << endl;
return 20;
}
- if (argc == 1) {
- aerr << "cmd: No service specified; use -l to list all services" << endl;
+ int argc = argv.size();
+
+ if (argc == 0) {
+ errorLog << "cmd: No service specified; use -l to list all services" << endl;
return 20;
}
- if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
+ if ((argc == 1) && (argv[0] == "-l")) {
Vector<String16> services = sm->listServices();
services.sort(sort_func);
- aout << "Currently running services:" << endl;
+ outputLog << "Currently running services:" << endl;
for (size_t i=0; i<services.size(); i++) {
sp<IBinder> service = sm->checkService(services[i]);
if (service != nullptr) {
- aout << " " << services[i] << endl;
+ outputLog << " " << services[i] << endl;
}
}
return 0;
}
+ const auto cmd = argv[0];
+
Vector<String16> args;
- for (int i=2; i<argc; i++) {
- args.add(String16(argv[i]));
+ String16 serviceName = String16(cmd.data(), cmd.size());
+ for (int i = 1; i < argc; i++) {
+ args.add(String16(argv[i].data(), argv[i].size()));
}
- String16 cmd = String16(argv[1]);
- sp<IBinder> service = sm->checkService(cmd);
+ sp<IBinder> service = sm->checkService(serviceName);
if (service == nullptr) {
- ALOGW("Can't find service %s", argv[1]);
- aerr << "cmd: Can't find service: " << argv[1] << endl;
+ if (runMode == RunMode::kStandalone) {
+ ALOGW("Can't find service %.*s", static_cast<int>(cmd.size()), cmd.data());
+ }
+ errorLog << "cmd: Can't find service: " << cmd << endl;
return 20;
}
- sp<MyShellCallback> cb = new MyShellCallback();
+ sp<MyShellCallback> cb = new MyShellCallback(errorLog);
sp<MyResultReceiver> result = new MyResultReceiver();
#if DEBUG
- ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", argv[1], STDIN_FILENO, STDOUT_FILENO,
- STDERR_FILENO);
+ ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", cmd, in, out, err);
#endif
// TODO: block until a result is returned to MyResultReceiver.
- status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args,
- cb, result);
- if (err < 0) {
+ status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);
+ if (error < 0) {
const char* errstr;
- switch (err) {
+ switch (error) {
case BAD_TYPE: errstr = "Bad type"; break;
case FAILED_TRANSACTION: errstr = "Failed transaction"; break;
case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break;
case UNEXPECTED_NULL: errstr = "Unexpected null"; break;
- default: errstr = strerror(-err); break;
+ default: errstr = strerror(-error); break;
}
- ALOGW("Failure calling service %s: %s (%d)", argv[1], errstr, -err);
- aout << "cmd: Failure calling service " << argv[1] << ": " << errstr << " ("
- << (-err) << ")" << endl;
- return err;
+ if (runMode == RunMode::kStandalone) {
+ ALOGW("Failure calling service %.*s: %s (%d)", static_cast<int>(cmd.size()), cmd.data(),
+ errstr, -error);
+ }
+ outputLog << "cmd: Failure calling service " << cmd << ": " << errstr << " (" << (-error)
+ << ")" << endl;
+ return error;
}
cb->mActive = false;
diff --git a/cmds/cmd/cmd.h b/cmds/cmd/cmd.h
new file mode 100644
index 0000000..a91e009
--- /dev/null
+++ b/cmds/cmd/cmd.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/TextOutput.h>
+
+#include <string_view>
+#include <vector>
+
+enum class RunMode {
+ kStandalone,
+ kLibrary,
+};
+
+int cmdMain(const std::vector<std::string_view>& argv, android::TextOutput& outputLog,
+ android::TextOutput& errorLog, int in, int out, int err, RunMode runMode);
diff --git a/cmds/cmd/main.cpp b/cmds/cmd/main.cpp
new file mode 100644
index 0000000..2256e2a
--- /dev/null
+++ b/cmds/cmd/main.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+
+#include "cmd.h"
+
+int main(int argc, char* const argv[]) {
+ signal(SIGPIPE, SIG_IGN);
+
+ std::vector<std::string_view> arguments;
+ arguments.reserve(argc - 1);
+ // 0th argument is a program name, skipping.
+ for (int i = 1; i < argc; ++i) {
+ arguments.emplace_back(argv[i]);
+ }
+
+ return cmdMain(arguments, android::aout, android::aerr, STDIN_FILENO, STDOUT_FILENO,
+ STDERR_FILENO, RunMode::kStandalone);
+}
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index d97ffbf..990fd43 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -871,7 +871,11 @@
is_java_process ? 5 : 20, fd);
if (ret == -1) {
- dprintf(fd, "dumping failed, likely due to a timeout\n");
+ // For consistency, the header and footer to this message match those
+ // dumped by debuggerd in the success case.
+ dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
+ dprintf(fd, "Dump failed, likely due to a timeout.\n");
+ dprintf(fd, "---- end %d ----", pid);
timeout_failures++;
continue;
}
diff --git a/include/OWNERS b/include/OWNERS
new file mode 100644
index 0000000..82ae4cf
--- /dev/null
+++ b/include/OWNERS
@@ -0,0 +1,17 @@
+alexeykuzmin@google.com
+brianderson@google.com
+dangittik@google.com
+lajos@google.com
+mathias@google.com
+michaelwr@google.com
+olv@google.com
+pceballos@google.com
+pengxu@google.com
+racarr@google.com
+romainguy@google.com
+ronghuawu@google.com
+sadmac@google.com
+santoscordon@google.com
+stoza@google.com
+svv@google.com
+wiley@google.com
diff --git a/libs/gui/FrameTimestamps.cpp b/libs/gui/FrameTimestamps.cpp
index 96e9a85..c04d907 100644
--- a/libs/gui/FrameTimestamps.cpp
+++ b/libs/gui/FrameTimestamps.cpp
@@ -158,7 +158,7 @@
namespace {
struct FrameNumberEqual {
- FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
+ explicit FrameNumberEqual(uint64_t frameNumber) : mFrameNumber(frameNumber) {}
bool operator()(const FrameEvents& frame) {
return frame.valid && mFrameNumber == frame.frameNumber;
}
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 68a6b1f..d997674 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -536,7 +536,7 @@
class HpGraphicBufferProducer : public HpInterface<
BpGraphicBufferProducer, H2BGraphicBufferProducer> {
public:
- HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {}
+ explicit HpGraphicBufferProducer(const sp<IBinder>& base) : PBase(base) {}
status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override {
return mBase->requestBuffer(slot, buf);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 799151a..a481e81 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -63,19 +63,10 @@
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
- virtual sp<ISurfaceComposerClient> createScopedConnection(
- const sp<IGraphicBufferProducer>& parent)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(parent));
- remote()->transact(BnSurfaceComposer::CREATE_SCOPED_CONNECTION, data, &reply);
- return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
- }
-
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken) {
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& commands) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -91,6 +82,7 @@
data.writeUint32(flags);
data.writeStrongBinder(applyToken);
+ commands.write(data);
remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
}
@@ -709,14 +701,6 @@
reply->writeStrongBinder(b);
return NO_ERROR;
}
- case CREATE_SCOPED_CONNECTION: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IGraphicBufferProducer> bufferProducer =
- interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
- sp<IBinder> b = IInterface::asBinder(createScopedConnection(bufferProducer));
- reply->writeStrongBinder(b);
- return NO_ERROR;
- }
case SET_TRANSACTION_STATE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
@@ -750,7 +734,9 @@
uint32_t stateFlags = data.readUint32();
sp<IBinder> applyToken = data.readStrongBinder();
- setTransactionState(state, displays, stateFlags, applyToken);
+ InputWindowCommands inputWindowCommands;
+ inputWindowCommands.read(data);
+ setTransactionState(state, displays, stateFlags, applyToken, inputWindowCommands);
return NO_ERROR;
}
case BOOT_FINISHED: {
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 35ce6e3..e5170ab 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -379,4 +379,36 @@
}
}
+// ------------------------------- InputWindowCommands ----------------------------------------
+
+void InputWindowCommands::merge(const InputWindowCommands& other) {
+ transferTouchFocusCommands
+ .insert(transferTouchFocusCommands.end(),
+ std::make_move_iterator(other.transferTouchFocusCommands.begin()),
+ std::make_move_iterator(other.transferTouchFocusCommands.end()));
+}
+
+void InputWindowCommands::clear() {
+ transferTouchFocusCommands.clear();
+}
+
+void InputWindowCommands::write(Parcel& output) const {
+ output.writeUint32(static_cast<uint32_t>(transferTouchFocusCommands.size()));
+ for (const auto& transferTouchFocusCommand : transferTouchFocusCommands) {
+ output.writeStrongBinder(transferTouchFocusCommand.fromToken);
+ output.writeStrongBinder(transferTouchFocusCommand.toToken);
+ }
+}
+
+void InputWindowCommands::read(const Parcel& input) {
+ size_t count = input.readUint32();
+ transferTouchFocusCommands.clear();
+ for (size_t i = 0; i < count; i++) {
+ TransferTouchFocusCommand transferTouchFocusCommand;
+ transferTouchFocusCommand.fromToken = input.readStrongBinder();
+ transferTouchFocusCommand.toToken = input.readStrongBinder();
+ transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+ }
+}
+
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 5b004e2..824e43f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -166,6 +166,7 @@
mEarlyWakeup(other.mEarlyWakeup) {
mDisplayStates = other.mDisplayStates;
mComposerStates = other.mComposerStates;
+ mInputWindowCommands = other.mInputWindowCommands;
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
@@ -199,6 +200,8 @@
}
other.mListenerCallbacks.clear();
+ mInputWindowCommands.merge(other.mInputWindowCommands);
+
return *this;
}
@@ -265,8 +268,8 @@
mEarlyWakeup = false;
sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
-
- sf->setTransactionState(composerStates, displayStates, flags, applyToken);
+ sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands);
+ mInputWindowCommands.clear();
mStatus = NO_ERROR;
return NO_ERROR;
}
@@ -804,6 +807,16 @@
s->what |= layer_state_t::eInputInfoChanged;
return *this;
}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::transferTouchFocus(
+ const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+ InputWindowCommands::TransferTouchFocusCommand transferTouchFocusCommand;
+ transferTouchFocusCommand.fromToken = fromToken;
+ transferTouchFocusCommand.toToken = toToken;
+ mInputWindowCommands.transferTouchFocusCommands.emplace_back(transferTouchFocusCommand);
+ return *this;
+}
+
#endif
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::destroySurface(
@@ -897,11 +910,6 @@
{
}
-SurfaceComposerClient::SurfaceComposerClient(const sp<IGraphicBufferProducer>& root)
- : mStatus(NO_INIT), mParent(root)
-{
-}
-
SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client)
: mStatus(NO_ERROR), mClient(client)
{
@@ -910,10 +918,8 @@
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
- auto rootProducer = mParent.promote();
sp<ISurfaceComposerClient> conn;
- conn = (rootProducer != nullptr) ? sf->createScopedConnection(rootProducer) :
- sf->createConnection();
+ conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 3a6dfda..b6ef286 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -54,6 +54,13 @@
{
}
+SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
+ mClient = other->mClient;
+ mHandle = other->mHandle;
+ mGraphicBufferProducer = other->mGraphicBufferProducer;
+ mOwned = false;
+}
+
SurfaceControl::~SurfaceControl()
{
destroy();
diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h
index d108120..aa13c0c 100644
--- a/libs/gui/include/gui/BufferQueueConsumer.h
+++ b/libs/gui/include/gui/BufferQueueConsumer.h
@@ -31,7 +31,7 @@
class BufferQueueConsumer : public BnGraphicBufferConsumer {
public:
- BufferQueueConsumer(const sp<BufferQueueCore>& core);
+ explicit BufferQueueConsumer(const sp<BufferQueueCore>& core);
~BufferQueueConsumer() override;
// acquireBuffer attempts to acquire ownership of the next pending buffer in
diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
index 5c7ffb4..73bc5dd 100644
--- a/libs/gui/include/gui/BufferQueueProducer.h
+++ b/libs/gui/include/gui/BufferQueueProducer.h
@@ -29,7 +29,8 @@
public:
friend class BufferQueue; // Needed to access binderDied
- BufferQueueProducer(const sp<BufferQueueCore>& core, bool consumerIsSurfaceFlinger = false);
+ explicit BufferQueueProducer(const sp<BufferQueueCore>& core,
+ bool consumerIsSurfaceFlinger = false);
~BufferQueueProducer() override;
// requestBuffer returns the GraphicBuffer for slot N.
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 32ce59a..a4102df 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -84,7 +84,7 @@
* or requestNextVsync to receive them.
* Other events start being delivered immediately.
*/
- DisplayEventReceiver(
+ explicit DisplayEventReceiver(
ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
/*
diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h
index 46a99e1..ddd868d 100644
--- a/libs/gui/include/gui/GLConsumer.h
+++ b/libs/gui/include/gui/GLConsumer.h
@@ -301,7 +301,7 @@
// also only creating new EGLImages from buffers when required.
class EglImage : public LightRefBase<EglImage> {
public:
- EglImage(sp<GraphicBuffer> graphicBuffer);
+ explicit EglImage(sp<GraphicBuffer> graphicBuffer);
// createIfNeeded creates an EGLImage if required (we haven't created
// one yet, or the EGLDisplay or crop-rect has changed).
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 8cb40e7..1534fca 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -42,6 +42,7 @@
struct DisplayState;
struct DisplayInfo;
struct DisplayStatInfo;
+struct InputWindowCommands;
class LayerDebugInfo;
class HdrCapabilities;
class IDisplayEventConnection;
@@ -86,22 +87,11 @@
eVsyncSourceSurfaceFlinger = 1
};
- /* create connection with surface flinger, requires
- * ACCESS_SURFACE_FLINGER permission
+ /*
+ * Create a connection with SurfaceFlinger.
*/
virtual sp<ISurfaceComposerClient> createConnection() = 0;
- /** create a scoped connection with surface flinger.
- * Surfaces produced with this connection will act
- * as children of the passed in GBP. That is to say
- * SurfaceFlinger will draw them relative and confined to
- * drawing of buffers from the layer associated with parent.
- * As this is graphically equivalent in reach to just drawing
- * pixels into the parent buffers, it requires no special permission.
- */
- virtual sp<ISurfaceComposerClient> createScopedConnection(
- const sp<IGraphicBufferProducer>& parent) = 0;
-
/* return an IDisplayEventConnection */
virtual sp<IDisplayEventConnection> createDisplayEventConnection(
VsyncSource vsyncSource = eVsyncSourceApp) = 0;
@@ -125,7 +115,8 @@
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken) = 0;
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands) = 0;
/* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission
@@ -354,7 +345,6 @@
ENABLE_VSYNC_INJECTIONS,
INJECT_VSYNC,
GET_LAYER_DEBUG_INFO,
- CREATE_SCOPED_CONNECTION,
GET_COMPOSITION_PREFERENCE,
GET_COLOR_MANAGEMENT,
GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 02c6be2..e7564f5 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -228,6 +228,20 @@
status_t read(const Parcel& input);
};
+struct InputWindowCommands {
+ struct TransferTouchFocusCommand {
+ sp<IBinder> fromToken;
+ sp<IBinder> toToken;
+ };
+
+ std::vector<TransferTouchFocusCommand> transferTouchFocusCommands;
+
+ void merge(const InputWindowCommands& other);
+ void clear();
+ void write(Parcel& output) const;
+ void read(const Parcel& input);
+};
+
static inline int compare_type(const ComposerState& lhs, const ComposerState& rhs) {
if (lhs.client < rhs.client) return -1;
if (lhs.client > rhs.client) return 1;
diff --git a/libs/gui/include/gui/StreamSplitter.h b/libs/gui/include/gui/StreamSplitter.h
index 8f47eb4..b4eef29 100644
--- a/libs/gui/include/gui/StreamSplitter.h
+++ b/libs/gui/include/gui/StreamSplitter.h
@@ -128,7 +128,7 @@
class BufferTracker : public LightRefBase<BufferTracker> {
public:
- BufferTracker(const sp<GraphicBuffer>& buffer);
+ explicit BufferTracker(const sp<GraphicBuffer>& buffer);
const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
const sp<Fence>& getMergedFence() const { return mMergedFence; }
@@ -154,7 +154,7 @@
};
// Only called from createSplitter
- StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue);
+ explicit StreamSplitter(const sp<IGraphicBufferConsumer>& inputQueue);
// Must be accessed through RefBase
virtual ~StreamSplitter();
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 8e3ba78..4a8e01b 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -90,7 +90,6 @@
public:
SurfaceComposerClient();
SurfaceComposerClient(const sp<ISurfaceComposerClient>& client);
- SurfaceComposerClient(const sp<IGraphicBufferProducer>& parent);
virtual ~SurfaceComposerClient();
// Always make sure we could initialize
@@ -219,6 +218,7 @@
bool mAnimation = false;
bool mEarlyWakeup = false;
+ InputWindowCommands mInputWindowCommands;
int mStatus = NO_ERROR;
layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
@@ -335,6 +335,7 @@
#ifndef NO_INPUT
Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const InputWindowInfo& info);
+ Transaction& transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
#endif
Transaction& destroySurface(const sp<SurfaceControl>& sc);
@@ -400,7 +401,6 @@
mutable Mutex mLock;
status_t mStatus;
sp<ISurfaceComposerClient> mClient;
- wp<IGraphicBufferProducer> mParent;
};
// ---------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index ccb30fa..9bba766 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -75,6 +75,8 @@
status_t getLayerFrameStats(FrameStats* outStats) const;
sp<SurfaceComposerClient> getClient() const;
+
+ explicit SurfaceControl(const sp<SurfaceControl>& other);
private:
// can't be copied
diff --git a/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
index fa6c2d9..0f6fb45 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/B2HProducerListener.h
@@ -50,7 +50,7 @@
struct B2HProducerListener : public HProducerListener {
sp<BProducerListener> mBase;
- B2HProducerListener(sp<BProducerListener> const& base);
+ explicit B2HProducerListener(sp<BProducerListener> const& base);
Return<void> onBufferReleased() override;
Return<bool> needsReleaseNotify() override;
};
diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
index 74850b4..c92fa9d 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
@@ -59,7 +59,7 @@
HGraphicBufferProducer,
BGraphicBufferProducer,
BnGraphicBufferProducer> {
- H2BGraphicBufferProducer(sp<HGraphicBufferProducer> const& base) : CBase(base) {}
+ explicit H2BGraphicBufferProducer(sp<HGraphicBufferProducer> const& base) : CBase(base) {}
status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) override;
diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp
index bb6b8a5..acd4297 100644
--- a/libs/gui/tests/Malicious.cpp
+++ b/libs/gui/tests/Malicious.cpp
@@ -27,7 +27,7 @@
class ProxyBQP : public BnGraphicBufferProducer {
public:
- ProxyBQP(const sp<IGraphicBufferProducer>& producer) : mProducer(producer) {}
+ explicit ProxyBQP(const sp<IGraphicBufferProducer>& producer) : mProducer(producer) {}
// Pass through calls to mProducer
status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override {
@@ -102,7 +102,7 @@
class MaliciousBQP : public ProxyBQP {
public:
- MaliciousBQP(const sp<IGraphicBufferProducer>& producer) : ProxyBQP(producer) {}
+ explicit MaliciousBQP(const sp<IGraphicBufferProducer>& producer) : ProxyBQP(producer) {}
void beMalicious(int32_t value) { mMaliciousValue = value; }
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index c56304f..60173dc 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -545,10 +545,6 @@
}
sp<ISurfaceComposerClient> createConnection() override { return nullptr; }
- sp<ISurfaceComposerClient> createScopedConnection(
- const sp<IGraphicBufferProducer>& /* parent */) override {
- return nullptr;
- }
sp<IDisplayEventConnection> createDisplayEventConnection(ISurfaceComposer::VsyncSource)
override {
return nullptr;
@@ -559,7 +555,8 @@
sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; }
void setTransactionState(const Vector<ComposerState>& /*state*/,
const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
- const sp<IBinder>& /*applyToken*/) override {}
+ const sp<IBinder>& /*applyToken*/,
+ const InputWindowCommands& /*inputWindowCommands*/) override {}
void bootFinished() override {}
bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& /*surface*/) const override {
@@ -669,8 +666,7 @@
class FakeProducerFrameEventHistory : public ProducerFrameEventHistory {
public:
- FakeProducerFrameEventHistory(FenceToFenceTimeMap* fenceMap)
- : mFenceMap(fenceMap) {}
+ explicit FakeProducerFrameEventHistory(FenceToFenceTimeMap* fenceMap) : mFenceMap(fenceMap) {}
~FakeProducerFrameEventHistory() {}
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index d872f02..ac053f3 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -26,6 +26,7 @@
"libgui",
"liblog",
"libnativewindow",
+ "libsync",
"libui",
"libutils",
],
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 51cf188..d0a0ac8 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -24,6 +24,7 @@
#include <math.h>
#include <fstream>
#include <sstream>
+#include <unordered_set>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -32,6 +33,7 @@
#include <renderengine/Mesh.h>
#include <renderengine/Texture.h>
#include <renderengine/private/Description.h>
+#include <sync/sync.h>
#include <ui/ColorSpace.h>
#include <ui/DebugUtils.h>
#include <ui/Rect.h>
@@ -584,6 +586,46 @@
}
}
+status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
+ sp<Fence> bufferFence) {
+ std::unique_ptr<Image> newImage = createImage();
+
+ bool created = newImage->setNativeWindowBuffer(buffer->getNativeBuffer(),
+ buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+ if (!created) {
+ ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d",
+ buffer->getWidth(), buffer->getHeight(), buffer->getStride(), buffer->getUsage(),
+ buffer->getPixelFormat());
+ bindExternalTextureImage(texName, *createImage());
+ return NO_INIT;
+ }
+
+ bindExternalTextureImage(texName, *newImage);
+
+ // Wait for the new buffer to be ready.
+ if (bufferFence != nullptr && bufferFence->isValid()) {
+ if (GLExtensions::getInstance().hasWaitSync()) {
+ base::unique_fd fenceFd(bufferFence->dup());
+ if (fenceFd == -1) {
+ ALOGE("error dup'ing fence fd: %d", errno);
+ return -errno;
+ }
+ if (!waitFence(std::move(fenceFd))) {
+ ALOGE("failed to wait on fence fd");
+ return UNKNOWN_ERROR;
+ }
+ } else {
+ status_t err = bufferFence->waitForever("RenderEngine::bindExternalTextureBuffer");
+ if (err != NO_ERROR) {
+ ALOGE("error waiting for fence: %d", err);
+ return err;
+ }
+ }
+ }
+
+ return NO_ERROR;
+}
+
status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
EGLImageKHR eglImage = glFramebuffer->getEGLImage();
@@ -673,32 +715,62 @@
mat4 projectionMatrix = mState.projectionMatrix * display.globalTransform;
- Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
+ Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
for (auto layer : layers) {
- // for now, assume that all pixel sources are solid colors.
- // TODO(alecmouri): support buffer sources
- if (layer.source.buffer.buffer != nullptr) {
- continue;
- }
-
- setColorTransform(display.colorTransform * layer.colorTransform);
-
mState.projectionMatrix = projectionMatrix * layer.geometry.positionTransform;
- FloatRect bounds = layer.geometry.boundaries;
+ const FloatRect bounds = layer.geometry.boundaries;
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
position[0] = vec2(bounds.left, bounds.top);
position[1] = vec2(bounds.left, bounds.bottom);
position[2] = vec2(bounds.right, bounds.bottom);
position[3] = vec2(bounds.right, bounds.top);
- half3 solidColor = layer.source.solidColor;
- half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha);
- setupLayerBlending(/*premultipliedAlpha=*/true, /*opaque=*/false, /*disableTexture=*/true,
+ setColorTransform(display.colorTransform * layer.colorTransform);
+
+ bool usePremultipliedAlpha = true;
+ bool disableTexture = true;
+
+ if (layer.source.buffer.buffer != nullptr) {
+ disableTexture = false;
+
+ sp<GraphicBuffer> gBuf = layer.source.buffer.buffer;
+
+ bindExternalTextureBuffer(layer.source.buffer.textureName, gBuf,
+ layer.source.buffer.fence);
+
+ usePremultipliedAlpha = layer.source.buffer.usePremultipliedAlpha;
+ Texture texture(Texture::TEXTURE_EXTERNAL, layer.source.buffer.textureName);
+ texture.setMatrix(layer.source.buffer.textureTransform.asArray());
+ texture.setFiltering(layer.source.buffer.useTextureFiltering);
+
+ texture.setDimensions(gBuf->getWidth(), gBuf->getHeight());
+ setSourceY410BT2020(layer.source.buffer.isY410BT2020);
+
+ renderengine::Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
+ texCoords[0] = vec2(0.0, 1.0);
+ texCoords[1] = vec2(0.0, 0.0);
+ texCoords[2] = vec2(1.0, 0.0);
+ texCoords[3] = vec2(1.0, 1.0);
+ setupLayerTexturing(texture);
+ }
+
+ const half3 solidColor = layer.source.solidColor;
+ const half4 color = half4(solidColor.r, solidColor.g, solidColor.b, layer.alpha);
+ // Buffer sources will have a black solid color ignored in the shader,
+ // so in that scenario the solid color passed here is arbitrary.
+ setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture,
color, /*cornerRadius=*/0.0);
setSourceDataSpace(layer.sourceDataspace);
drawMesh(mesh);
+
+ // Cleanup if there's a buffer source
+ if (layer.source.buffer.buffer != nullptr) {
+ disableBlending();
+ setSourceY410BT2020(false);
+ disableTexturing();
+ }
}
*drawFence = flush();
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index b6fff33..2af2aed 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -127,6 +127,7 @@
// Defines the viewport, and sets the projection matrix to the projection
// defined by the clip.
void setViewportAndProjection(Rect viewport, Rect clip);
+ status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence);
EGLDisplay mEGLDisplay;
EGLConfig mEGLConfig;
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index 93abf5c..a37a163 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -19,6 +19,7 @@
#include <math/mat4.h>
#include <math/vec3.h>
#include <renderengine/Texture.h>
+#include <ui/Fence.h>
#include <ui/FloatRect.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
@@ -36,6 +37,9 @@
// ignored.
sp<GraphicBuffer> buffer = nullptr;
+ // Fence that will fire when the buffer is ready to be bound.
+ sp<Fence> fence = nullptr;
+
// Texture identifier to bind the external texture to.
// TODO(alecmouri): This is GL-specific...make the type backend-agnostic.
uint32_t textureName = 0;
@@ -49,6 +53,11 @@
// Wheteher to use pre-multiplied alpha
bool usePremultipliedAlpha = true;
+ // Override flag that alpha for each pixel in the buffer *must* be 1.0.
+ // LayerSettings::alpha is still used if isOpaque==true - this flag only
+ // overrides the alpha channel of the buffer.
+ bool isOpaque = false;
+
// HDR color-space setting for Y410.
bool isY410BT2020 = false;
};
@@ -81,7 +90,7 @@
// Source pixels for this layer.
PixelSource source = PixelSource();
- // Alpha option to apply to the source pixels
+ // Alpha option to blend with the source pixels
half alpha = half(0.0);
// Color space describing how the source pixels should be interpreted.
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index a0542dd..e43ee37 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -27,15 +27,30 @@
namespace android {
struct RenderEngineTest : public ::testing::Test {
- sp<GraphicBuffer> allocateDefaultBuffer() {
+ static sp<GraphicBuffer> allocateDefaultBuffer() {
return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+ GRALLOC_USAGE_HW_RENDER,
"output");
}
+ // Allocates a 1x1 buffer to fill with a solid color
+ static sp<GraphicBuffer> allocateSourceBuffer(uint32_t width, uint32_t height) {
+ return new GraphicBuffer(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+ GRALLOC_USAGE_HW_TEXTURE,
+ "input");
+ }
+
RenderEngineTest() { mBuffer = allocateDefaultBuffer(); }
+ ~RenderEngineTest() {
+ for (uint32_t texName : mTexNames) {
+ sRE->deleteTextures(1, &texName);
+ }
+ }
+
void expectBufferColor(const Rect& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
uint8_t tolerance = 0) {
uint8_t* pixels;
@@ -146,27 +161,100 @@
void fillBufferCheckersRotate270();
template <typename SourceVariant>
+ void fillBufferWithLayerTransform();
+
+ template <typename SourceVariant>
void fillBufferLayerTransform();
template <typename SourceVariant>
+ void fillBufferWithColorTransform();
+
+ template <typename SourceVariant>
void fillBufferColorTransform();
+ void fillRedBufferTextureTransform();
+
+ void fillBufferTextureTransform();
+
+ void fillRedBufferWithPremultiplyAlpha();
+
+ void fillBufferWithPremultiplyAlpha();
+
+ void fillRedBufferWithoutPremultiplyAlpha();
+
+ void fillBufferWithoutPremultiplyAlpha();
+
// Dumb hack to get aroud the fact that tear-down for renderengine isn't
// well defined right now, so we can't create multiple instances
static std::unique_ptr<renderengine::RenderEngine> sRE;
sp<GraphicBuffer> mBuffer;
+
+ std::vector<uint32_t> mTexNames;
};
std::unique_ptr<renderengine::RenderEngine> RenderEngineTest::sRE =
renderengine::RenderEngine::create(static_cast<int32_t>(ui::PixelFormat::RGBA_8888), 0);
struct ColorSourceVariant {
- static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b) {
+ static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
+ RenderEngineTest* /*fixture*/) {
layer.source.solidColor = half3(r, g, b);
}
};
+struct RelaxOpaqueBufferVariant {
+ static void setOpaqueBit(renderengine::LayerSettings& layer) {
+ layer.source.buffer.isOpaque = false;
+ }
+
+ static uint8_t getAlphaChannel() { return 255; }
+};
+
+struct ForceOpaqueBufferVariant {
+ static void setOpaqueBit(renderengine::LayerSettings& layer) {
+ layer.source.buffer.isOpaque = true;
+ }
+
+ static uint8_t getAlphaChannel() {
+ // The isOpaque bit will override the alpha channel, so this should be
+ // arbitrary.
+ return 10;
+ }
+};
+
+template <typename OpaquenessVariant>
+struct BufferSourceVariant {
+ static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
+ RenderEngineTest* fixture) {
+ sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1);
+ uint32_t texName;
+ RenderEngineTest::sRE->genTextures(1, &texName);
+ fixture->mTexNames.push_back(texName);
+
+ uint8_t* pixels;
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
+
+ for (int32_t j = 0; j < buf->getHeight(); j++) {
+ uint8_t* iter = pixels + (buf->getStride() * j) * 4;
+ for (int32_t i = 0; i < buf->getWidth(); i++) {
+ iter[0] = uint8_t(r * 255);
+ iter[1] = uint8_t(g * 255);
+ iter[2] = uint8_t(b * 255);
+ iter[3] = OpaquenessVariant::getAlphaChannel();
+ iter += 4;
+ }
+ }
+
+ buf->unlock();
+
+ layer.source.buffer.buffer = buf;
+ layer.source.buffer.textureName = texName;
+ OpaquenessVariant::setOpaqueBit(layer);
+ }
+};
+
template <typename SourceVariant>
void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
renderengine::DisplaySettings settings;
@@ -177,7 +265,7 @@
renderengine::LayerSettings layer;
layer.geometry.boundaries = fullscreenRect().toFloatRect();
- SourceVariant::fillColor(layer, r, g, b);
+ SourceVariant::fillColor(layer, r, g, b, this);
layer.alpha = a;
layers.push_back(layer);
@@ -219,7 +307,7 @@
renderengine::LayerSettings layer;
layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
- SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f);
+ SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
layer.alpha = 1.0f;
layers.push_back(layer);
@@ -253,19 +341,19 @@
renderengine::LayerSettings layerOne;
Rect rectOne(0, 0, 1, 1);
layerOne.geometry.boundaries = rectOne.toFloatRect();
- SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f);
+ SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
layerOne.alpha = 1.0f;
renderengine::LayerSettings layerTwo;
Rect rectTwo(0, 1, 1, 2);
layerTwo.geometry.boundaries = rectTwo.toFloatRect();
- SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f);
+ SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
layerTwo.alpha = 1.0f;
renderengine::LayerSettings layerThree;
Rect rectThree(1, 0, 2, 1);
layerThree.geometry.boundaries = rectThree.toFloatRect();
- SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f);
+ SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
layerThree.alpha = 1.0f;
layers.push_back(layerOne);
@@ -343,7 +431,7 @@
}
template <typename SourceVariant>
-void RenderEngineTest::fillBufferLayerTransform() {
+void RenderEngineTest::fillBufferWithLayerTransform() {
renderengine::DisplaySettings settings;
settings.physicalDisplay = fullscreenRect();
// Here logical space is 2x2
@@ -355,13 +443,18 @@
layer.geometry.boundaries = Rect(1, 1).toFloatRect();
// Translate one pixel diagonally
layer.geometry.positionTransform = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1);
+ SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
layer.alpha = 1.0f;
layers.push_back(layer);
invokeDraw(settings, layers, mBuffer);
+}
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferLayerTransform() {
+ fillBufferWithLayerTransform<SourceVariant>();
expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
@@ -370,7 +463,7 @@
}
template <typename SourceVariant>
-void RenderEngineTest::fillBufferColorTransform() {
+void RenderEngineTest::fillBufferWithColorTransform() {
renderengine::DisplaySettings settings;
settings.physicalDisplay = fullscreenRect();
settings.clip = Rect(1, 1);
@@ -379,7 +472,7 @@
renderengine::LayerSettings layer;
layer.geometry.boundaries = Rect(1, 1).toFloatRect();
- layer.source.solidColor = half3(0.5f, 0.25f, 0.125f);
+ SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
layer.alpha = 1.0f;
// construct a fake color matrix
@@ -388,13 +481,148 @@
// set red channel to red + green
layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
+ layer.alpha = 1.0f;
+ layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
layers.push_back(layer);
invokeDraw(settings, layers, mBuffer);
+}
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferColorTransform() {
+ fillBufferWithColorTransform<SourceVariant>();
expectBufferColor(fullscreenRect(), 191, 0, 0, 255);
}
+void RenderEngineTest::fillRedBufferTextureTransform() {
+ renderengine::DisplaySettings settings;
+ settings.physicalDisplay = fullscreenRect();
+ settings.clip = Rect(1, 1);
+
+ std::vector<renderengine::LayerSettings> layers;
+
+ renderengine::LayerSettings layer;
+ // Here will allocate a checker board texture, but transform texture
+ // coordinates so that only the upper left is applied.
+ sp<GraphicBuffer> buf = allocateSourceBuffer(2, 2);
+ uint32_t texName;
+ RenderEngineTest::sRE->genTextures(1, &texName);
+ this->mTexNames.push_back(texName);
+
+ uint8_t* pixels;
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
+ // Red top left, Green top right, Blue bottom left, Black bottom right
+ pixels[0] = 255;
+ pixels[1] = 0;
+ pixels[2] = 0;
+ pixels[3] = 255;
+ pixels[4] = 0;
+ pixels[5] = 255;
+ pixels[6] = 0;
+ pixels[7] = 255;
+ pixels[8] = 0;
+ pixels[9] = 0;
+ pixels[10] = 255;
+ pixels[11] = 255;
+ buf->unlock();
+
+ layer.source.buffer.buffer = buf;
+ layer.source.buffer.textureName = texName;
+ // Transform coordinates to only be inside the red quadrant.
+ layer.source.buffer.textureTransform = mat4::scale(vec4(0.2, 0.2, 1, 1));
+ layer.alpha = 1.0f;
+ layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
+ layers.push_back(layer);
+
+ invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferTextureTransform() {
+ fillRedBufferTextureTransform();
+ expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
+}
+
+void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
+ renderengine::DisplaySettings settings;
+ settings.physicalDisplay = fullscreenRect();
+ // Here logical space is 1x1
+ settings.clip = Rect(1, 1);
+
+ std::vector<renderengine::LayerSettings> layers;
+
+ renderengine::LayerSettings layer;
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+ uint32_t texName;
+ RenderEngineTest::sRE->genTextures(1, &texName);
+ this->mTexNames.push_back(texName);
+
+ uint8_t* pixels;
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
+ pixels[0] = 255;
+ pixels[1] = 0;
+ pixels[2] = 0;
+ pixels[3] = 255;
+ buf->unlock();
+
+ layer.source.buffer.buffer = buf;
+ layer.source.buffer.textureName = texName;
+ layer.source.buffer.usePremultipliedAlpha = true;
+ layer.alpha = 0.5f;
+ layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
+ layers.push_back(layer);
+
+ invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
+ fillRedBufferWithPremultiplyAlpha();
+ expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
+}
+
+void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
+ renderengine::DisplaySettings settings;
+ settings.physicalDisplay = fullscreenRect();
+ // Here logical space is 1x1
+ settings.clip = Rect(1, 1);
+
+ std::vector<renderengine::LayerSettings> layers;
+
+ renderengine::LayerSettings layer;
+ sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
+ uint32_t texName;
+ RenderEngineTest::sRE->genTextures(1, &texName);
+ this->mTexNames.push_back(texName);
+
+ uint8_t* pixels;
+ buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ reinterpret_cast<void**>(&pixels));
+ pixels[0] = 255;
+ pixels[1] = 0;
+ pixels[2] = 0;
+ pixels[3] = 255;
+ buf->unlock();
+
+ layer.source.buffer.buffer = buf;
+ layer.source.buffer.textureName = texName;
+ layer.source.buffer.usePremultipliedAlpha = false;
+ layer.alpha = 0.5f;
+ layer.geometry.boundaries = Rect(1, 1).toFloatRect();
+
+ layers.push_back(layer);
+
+ invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
+ fillRedBufferWithoutPremultiplyAlpha();
+ expectBufferColor(fullscreenRect(), 128, 0, 0, 64, 1);
+}
+
TEST_F(RenderEngineTest, drawLayers_noLayersToDraw) {
drawEmptyLayers();
}
@@ -443,4 +671,104 @@
fillBufferLayerTransform<ColorSourceVariant>();
}
+TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
+ fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
+ fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
+ fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
+ fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
+ fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
+ fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
+ fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
+ fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
+ fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
+ fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
+ fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
+ fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
+ fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
+ fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
+ fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
+ fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
+ fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
+ fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
+ fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
+ fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
+ fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
+ fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
+ fillBufferTextureTransform();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
+ fillBufferWithPremultiplyAlpha();
+}
+
+TEST_F(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
+ fillBufferWithoutPremultiplyAlpha();
+}
+
} // namespace android
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index c80b79a..25958e2 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -208,6 +208,7 @@
defaults: ["gles_libs_defaults"],
srcs: ["GLES2/gl2.cpp"],
cflags: ["-DLOG_TAG=\"libGLESv2\""],
+ version_script: "libGLESv2.map.txt",
}
//##############################################################################
@@ -218,4 +219,5 @@
defaults: ["gles_libs_defaults"],
srcs: ["GLES2/gl2.cpp"],
cflags: ["-DLOG_TAG=\"libGLESv3\""],
+ version_script: "libGLESv3.map.txt",
}
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index 297e0c4..00caff2 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -106,7 +106,7 @@
.flags = ANDROID_DLEXT_USE_NAMESPACE,
.library_namespace = ns,
};
- void* so = android_dlopen_ext("libEGL_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ void* so = android_dlopen_ext("libGLESv2_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
angleGetDisplayPlatform =
reinterpret_cast<GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
diff --git a/opengl/libs/libGLESv1_CM.map.txt b/opengl/libs/libGLESv1_CM.map.txt
index 8ba91e6..41bf4ca 100644
--- a/opengl/libs/libGLESv1_CM.map.txt
+++ b/opengl/libs/libGLESv1_CM.map.txt
@@ -179,6 +179,7 @@
glLoadPaletteFromModelViewMatrixOES;
glLogicOp;
glMapBufferOES;
+ glMapBufferRangeEXT;
glMaterialf;
glMaterialfv;
glMaterialx;
diff --git a/opengl/libs/libGLESv2.map.txt b/opengl/libs/libGLESv2.map.txt
index 787c835..844d1e2 100644
--- a/opengl/libs/libGLESv2.map.txt
+++ b/opengl/libs/libGLESv2.map.txt
@@ -1,19 +1,28 @@
LIBGLESV2 {
global:
+ glActiveShaderProgramEXT;
glActiveTexture;
glAttachShader;
+ glBeginQueryEXT;
glBeginPerfMonitorAMD;
glBindAttribLocation;
glBindBuffer;
+ glBindFragDataLocationEXT; # introduced=24
+ glBindFragDataLocationIndexedEXT; # introduced=24
glBindFramebuffer;
+ glBindProgramPipelineEXT;
glBindRenderbuffer;
glBindTexture;
glBindVertexArrayOES; # introduced-mips=9 introduced-x86=9
glBlendColor;
glBlendEquation;
+ glBlendEquationiOES; # introduced=24
glBlendEquationSeparate;
+ glBlendEquationSeparateiOES; # introduced=24
glBlendFunc;
+ glBlendFunciOES; # introduced=24
glBlendFuncSeparate;
+ glBlendFuncSeparateiOES; # introduced=24
glBufferData;
glBufferSubData;
glCheckFramebufferStatus;
@@ -22,6 +31,7 @@
glClearDepthf;
glClearStencil;
glColorMask;
+ glColorMaskiOES; # introduced=24
glCompileShader;
glCompressedTexImage2D;
glCompressedTexImage3DOES;
@@ -34,12 +44,16 @@
glCoverageOperationNV; # introduced-mips=9 introduced-x86=9
glCreateProgram;
glCreateShader;
+ glCreateShaderProgramvEXT;
glCullFace;
+ glDebugMessageCallbackKHR; # introduced=21
glDeleteBuffers;
glDeleteFencesNV;
glDeleteFramebuffers;
glDeletePerfMonitorsAMD;
glDeleteProgram;
+ glDeleteProgramPipelinesEXT;
+ glDeleteQueriesEXT;
glDeleteRenderbuffers;
glDeleteShader;
glDeleteTextures;
@@ -49,17 +63,32 @@
glDepthRangef;
glDetachShader;
glDisable;
+ glDisableiOES; # introduced=24
glDisableDriverControlQCOM;
glDisableVertexAttribArray;
glDiscardFramebufferEXT; # introduced-mips=9 introduced-x86=9
glDrawArrays;
+ glDrawArraysInstancedBaseInstanceEXT; # introduced=24
+ glDrawArraysInstancedEXT; # introduced=21
+ glDrawBuffersEXT; # introduced=21
+ glDrawBuffersIndexedEXT; # introduced=21
glDrawElements;
+ glDrawElementsBaseVertexEXT; # introduced=24
+ glDrawElementsBaseVertexOES; # introduced=24
+ glDrawElementsInstancedBaseInstanceEXT; # introduced=24
+ glDrawElementsInstancedBaseVertexEXT; # introduced=24
+ glDrawElementsInstancedBaseVertexOES; # introduced=24
+ glDrawElementsInstancedBaseVertexBaseInstanceEXT; # introduced=24
+ glDrawRangeElementsBaseVertexEXT; # introduced=24
+ glDrawRangeElementsBaseVertexOES; # introduced=24
glEGLImageTargetRenderbufferStorageOES;
glEGLImageTargetTexture2DOES;
glEnable;
+ glEnableiOES; # introduced=24
glEnableDriverControlQCOM;
glEnableVertexAttribArray;
glEndPerfMonitorAMD;
+ glEndQueryEXT;
glEndTilingQCOM; # introduced-mips=9 introduced-x86=9
glExtGetBufferPointervQCOM; # introduced-mips=9 introduced-x86=9
glExtGetBuffersQCOM; # introduced-mips=9 introduced-x86=9
@@ -76,17 +105,20 @@
glFinish;
glFinishFenceNV;
glFlush;
+ glFlushMappedBufferRangeEXT; # introduced=21
glFramebufferRenderbuffer;
glFramebufferTexture2D;
glFramebufferTexture2DMultisampleIMG; # introduced-mips=9 introduced-x86=9
glFramebufferTexture2DMultisampleEXT; # introduced=28
glFramebufferTexture3DOES;
+ glFramebufferTextureOES; # introduced=24
glFrontFace;
glGenBuffers;
glGenFencesNV;
glGenFramebuffers;
glGenPerfMonitorsAMD;
glGenRenderbuffers;
+ glGenQueriesEXT;
glGenTextures;
glGenVertexArraysOES; # introduced-mips=9 introduced-x86=9
glGenerateMipmap;
@@ -102,24 +134,49 @@
glGetError;
glGetFenceivNV;
glGetFloatv;
+ glGetFragDataIndexEXT; # introduced=24
glGetFramebufferAttachmentParameteriv;
+ glGetGraphicsResetStatusEXT;
+ glGetGraphicsResetStatusKHR; # introduced=24
+ glGetIntegeri_vEXT; # introduced=21
glGetIntegerv;
+ glGetnUniformfvEXT;
+ glGetnUniformfvKHR; # introduced=24
+ glGetnUniformivEXT;
+ glGetnUniformivKHR; # introduced=24
+ glGetnUniformuivKHR; # introduced=24
+ glGetObjectLabelEXT;
+ glCopyImageSubDataOES; # introduced=24
glGetPerfMonitorCounterDataAMD;
glGetPerfMonitorCounterInfoAMD;
glGetPerfMonitorCounterStringAMD;
glGetPerfMonitorCountersAMD;
glGetPerfMonitorGroupStringAMD;
glGetPerfMonitorGroupsAMD;
+ glGetPointervKHR; # introduced=21
glGetProgramBinaryOES;
glGetProgramInfoLog;
glGetProgramiv;
+ glGenProgramPipelinesEXT;
+ glGetProgramPipelineInfoLogEXT;
+ glGetProgramPipelineivEXT;
+ glGetProgramResourceLocationIndexEXT; # introduced=24
+ glGetQueryivEXT;
+ glGetQueryObjectivEXT; # introduced=21
+ glGetQueryObjectuivEXT;
+ glGetQueryObjecti64vEXT; # introduced=21
+ glGetQueryObjectui64vEXT; # introduced=21
glGetRenderbufferParameteriv;
+ glGetSamplerParameterIivOES; # introduced=24
+ glGetSamplerParameterIuivOES; # introduced=24
glGetShaderInfoLog;
glGetShaderPrecisionFormat;
glGetShaderSource;
glGetShaderiv;
glGetString;
glGetTexParameterfv;
+ glGetTexParameterIivOES; # introduced=24
+ glGetTexParameterIuivOES; # introduced=24
glGetTexParameteriv;
glGetUniformLocation;
glGetUniformfv;
@@ -128,29 +185,83 @@
glGetVertexAttribfv;
glGetVertexAttribiv;
glHint;
+ glInsertEventMarkerEXT;
glIsBuffer;
glIsEnabled;
+ glIsEnablediOES; # introduced=24
glIsFenceNV;
glIsFramebuffer;
glIsProgram;
+ glIsProgramPipelineEXT;
+ glIsQueryEXT;
glIsRenderbuffer;
glIsShader;
glIsTexture;
glIsVertexArrayOES; # introduced-mips=9 introduced-x86=9
+ glLabelObjectEXT;
glLineWidth;
glLinkProgram;
glMapBufferOES;
glMultiDrawArraysEXT; # introduced-mips=9 introduced-x86=9
+ glMultiDrawArraysIndirectEXT; # introduced=24
+ glMultiDrawElementsIndirectEXT; # introduced=24
+ glMultiDrawElementsBaseVertexEXT; # introduced=24
+ glDrawElementsInstancedEXT; # introduced=21
glMultiDrawElementsEXT; # introduced-mips=9 introduced-x86=9
+ glPatchParameteriOES; # introduced=24
glPixelStorei;
glPolygonOffset;
+ glPopGroupMarkerEXT; # introduced=21
+ glPrimitiveBoundingBoxOES; # introduced=24
glProgramBinaryOES;
+ glProgramParameteriEXT;
+ glProgramUniform1fEXT;
+ glProgramUniform1fvEXT;
+ glProgramUniform1iEXT;
+ glProgramUniform1ivEXT;
+ glProgramUniform1uiEXT; # introduced=21
+ glProgramUniform1uivEXT; # introduced=21
+ glProgramUniform2fEXT;
+ glProgramUniform2fvEXT;
+ glProgramUniform2iEXT;
+ glProgramUniform2ivEXT;
+ glProgramUniform2uiEXT; # introduced=21
+ glProgramUniform2uivEXT; # introduced=21
+ glProgramUniform3fEXT;
+ glProgramUniform3fvEXT;
+ glProgramUniform3iEXT;
+ glProgramUniform3ivEXT;
+ glProgramUniform3uiEXT; # introduced=21
+ glProgramUniform3uivEXT; # introduced=21
+ glProgramUniform4fEXT;
+ glProgramUniform4fvEXT;
+ glProgramUniform4iEXT;
+ glProgramUniform4ivEXT;
+ glProgramUniform4uiEXT; # introduced=21
+ glProgramUniform4uivEXT; # introduced=21
+ glProgramUniformMatrix2fvEXT;
+ glProgramUniformMatrix2x3fvEXT; # introduced=21
+ glProgramUniformMatrix2x4fvEXT; # introduced=21
+ glProgramUniformMatrix3fvEXT;
+ glProgramUniformMatrix3x2fvEXT; # introduced=21
+ glProgramUniformMatrix3x4fvEXT; # introduced=21
+ glProgramUniformMatrix4fvEXT;
+ glProgramUniformMatrix4x2fvEXT; # introduced=21
+ glProgramUniformMatrix4x3fvEXT; # introduced=21
+ glPushGroupMarkerEXT;
+ glQueryCounterEXT; # introduced=21
+ glRasterSamplesEXT; # introduced=24
+ glReadBufferIndexedEXT; # introduced=21
+ glReadnPixelsEXT;
+ glReadnPixelsKHR; # introduced=24
glReadPixels;
glReleaseShaderCompiler;
glRenderbufferStorage;
glRenderbufferStorageMultisampleEXT; # introduced=28
glRenderbufferStorageMultisampleIMG; # introduced-mips=9 introduced-x86=9
glSampleCoverage;
+ glSamplerParameterIivOES; # introduced=24
+ glSamplerParameterIuivOES; # introduced=24
glScissor;
glSelectPerfMonitorCountersAMD;
glSetFenceNV;
@@ -164,14 +275,27 @@
glStencilOp;
glStencilOpSeparate;
glTestFenceNV;
+ glTexBufferOES; # introduced=24
+ glTexBufferRangeOES; # introduced=24
glTexImage2D;
glTexImage3DOES;
+ glTexPageCommitmentEXT; # introduced=24
glTexParameterf;
glTexParameterfv;
glTexParameteri;
+ glTexParameterIivOES; # introduced=24
+ glTexParameterIuivOES; # introduced=24
glTexParameteriv;
+ glTexStorage1DEXT;
+ glTexStorage2DEXT;
+ glTexStorage3DEXT;
glTexSubImage2D;
glTexSubImage3DOES;
+ glTextureStorage1DEXT;
+ glTextureStorage2DEXT;
+ glTextureStorage3DEXT;
+ glTextureViewEXT; # introduced=21
+ glTextureViewOES; # introduced=24
glUniform1f;
glUniform1fv;
glUniform1i;
@@ -193,7 +317,11 @@
glUniformMatrix4fv;
glUnmapBufferOES;
glUseProgram;
+ glUseProgramStagesEXT;
glValidateProgram;
+ glValidateProgramPipelineEXT;
+ glVertexAttribDivisorANGLE; # introduced=21
+ glVertexAttribDivisorEXT; # introduced=21
glVertexAttrib1f;
glVertexAttrib1fv;
glVertexAttrib2f;
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 0d8d34f..843eb37 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -22,6 +22,7 @@
shared_libs: [
"libinputflinger_base",
+ "libinputreporter",
"libinputreader",
"libbase",
"libbinder",
@@ -125,6 +126,35 @@
],
}
+cc_library_shared {
+ name: "libinputreporter",
+
+ srcs: [
+ "InputReporter.cpp",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libutils",
+ ],
+
+ header_libs: [
+ "libinputflinger_headers",
+ ],
+
+ export_header_lib_headers: [
+ "libinputflinger_headers",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
+}
+
subdirs = [
"host",
"tests",
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 7fa9cb6..6173452 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -257,6 +257,7 @@
mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false);
+ mReporter = createInputReporter();
mKeyRepeatState.lastKeyEntry = nullptr;
@@ -841,6 +842,7 @@
if (*dropReason != DROP_REASON_NOT_DROPPED) {
setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
+ mReporter->reportDroppedKey(entry->sequenceNum);
return true;
}
@@ -4025,6 +4027,10 @@
bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
if (keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK) {
+ if (!handled) {
+ // Report the key as unhandled, since the fallback was not handled.
+ mReporter->reportUnhandledKey(keyEntry->sequenceNum);
+ }
return false;
}
@@ -4192,6 +4198,9 @@
#if DEBUG_OUTBOUND_EVENT_DETAILS
ALOGD("Unhandled key event: No fallback key.");
#endif
+
+ // Report the key as unhandled, since there is no fallback key.
+ mReporter->reportUnhandledKey(keyEntry->sequenceNum);
}
}
return false;
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 05b5dad..7e6de6a 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -37,6 +37,7 @@
#include <unordered_map>
#include "InputListener.h"
+#include "InputReporter.h"
namespace android {
@@ -1186,6 +1187,8 @@
void traceInboundQueueLengthLocked();
void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
void traceWaitQueueLengthLocked(const sp<Connection>& connection);
+
+ sp<InputReporter> mReporter;
};
/* Enqueues and dispatches input events, endlessly. */
diff --git a/services/inputflinger/InputReporter.cpp b/services/inputflinger/InputReporter.cpp
new file mode 100644
index 0000000..cf4220f
--- /dev/null
+++ b/services/inputflinger/InputReporter.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "InputReporter.h"
+
+namespace android {
+
+// --- InputReporter ---
+
+void InputReporter::reportUnhandledKey(uint32_t sequenceNum) {
+ // do nothing
+}
+
+void InputReporter::reportDroppedKey(uint32_t sequenceNum) {
+ // do nothing
+}
+
+sp<InputReporter> createInputReporter() {
+ return new InputReporter();
+}
+
+} // namespace android
diff --git a/services/inputflinger/include/InputReporter.h b/services/inputflinger/include/InputReporter.h
new file mode 100644
index 0000000..c86dcda
--- /dev/null
+++ b/services/inputflinger/include/InputReporter.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_REPORTER_H
+#define _UI_INPUT_REPORTER_H
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+/*
+ * The interface used by the InputDispatcher to report information about input events after
+ * it is sent to the application, such as if a key is unhandled or dropped.
+ */
+class InputReporter: public virtual RefBase {
+protected:
+ virtual ~InputReporter() { }
+
+public:
+ // Report a key that was not handled by the system or apps.
+ // A key event is unhandled if:
+ // - The event was not handled and there is no fallback key; or
+ // - The event was not handled and it has a fallback key,
+ // but the fallback key was not handled.
+ virtual void reportUnhandledKey(uint32_t sequenceNum);
+
+ // Report a key that was dropped by InputDispatcher.
+ // A key can be dropped for several reasons. See the enum
+ // InputDispatcher::DropReason for details.
+ virtual void reportDroppedKey(uint32_t sequenceNum);
+};
+
+/*
+ * Factory method for InputReporter.
+ */
+sp<InputReporter> createInputReporter();
+
+} // namespace android
+
+#endif // _UI_INPUT_REPORTER_H
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 0e46928..077be86 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -141,6 +141,16 @@
int w = frame.getWidth();
int h = frame.getHeight();
+ if (x < 0) {
+ x = 0;
+ w = frame.right;
+ }
+
+ if (y < 0) {
+ y = 0;
+ h = frame.bottom;
+ }
+
Mutex::Autolock lock(mStateMutex);
if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y &&
mState.current.active.w == w && mState.current.active.h == h) {
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0b59147..ee4ec50 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -35,13 +35,7 @@
// ---------------------------------------------------------------------------
Client::Client(const sp<SurfaceFlinger>& flinger)
- : Client(flinger, nullptr)
-{
-}
-
-Client::Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer)
- : mFlinger(flinger),
- mParentLayer(parentLayer)
+ : mFlinger(flinger)
{
}
@@ -65,25 +59,6 @@
}
}
-void Client::updateParent(const sp<Layer>& parentLayer) {
- Mutex::Autolock _l(mLock);
-
- // If we didn't ever have a parent, then we must instead be
- // relying on permissions and we never need a parent.
- if (mParentLayer != nullptr) {
- mParentLayer = parentLayer;
- }
-}
-
-sp<Layer> Client::getParentLayer(bool* outParentDied) const {
- Mutex::Autolock _l(mLock);
- sp<Layer> parent = mParentLayer.promote();
- if (outParentDied != nullptr) {
- *outParentDied = (mParentLayer != nullptr && parent == nullptr);
- }
- return parent;
-}
-
status_t Client::initCheck() const {
return NO_ERROR;
}
@@ -119,32 +94,6 @@
}
-status_t Client::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- // these must be checked
- IPCThreadState* ipc = IPCThreadState::self();
- const int pid = ipc->getCallingPid();
- const int uid = ipc->getCallingUid();
- const int self_pid = getpid();
- // If we are called from another non root process without the GRAPHICS, SYSTEM, or ROOT
- // uid we require the sAccessSurfaceFlinger permission.
- // We grant an exception in the case that the Client has a "parent layer", as its
- // effects will be scoped to that layer.
- if (CC_UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != AID_SYSTEM && uid != 0)
- && (getParentLayer() == nullptr)) {
- // we're called from a different process, do the real check
- if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger))
- {
- ALOGE("Permission Denial: "
- "can't openGlobalTransaction pid=%d, uid<=%d", pid, uid);
- return PERMISSION_DENIED;
- }
- }
- return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
-}
-
-
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
@@ -160,16 +109,8 @@
return NAME_NOT_FOUND;
}
}
- if (parent == nullptr) {
- bool parentDied;
- parent = getParentLayer(&parentDied);
- // If we had a parent, but it died, we've lost all
- // our capabilities.
- if (parentDied) {
- return NAME_NOT_FOUND;
- }
- }
+ // We rely on createLayer to check permissions.
return mFlinger->createLayer(name, this, w, h, format, flags, windowType,
ownerUid, handle, gbp, &parent);
}
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 49437ed..4a74739 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -39,7 +39,6 @@
{
public:
explicit Client(const sp<SurfaceFlinger>& flinger);
- Client(const sp<SurfaceFlinger>& flinger, const sp<Layer>& parentLayer);
~Client();
status_t initCheck() const;
@@ -51,8 +50,6 @@
sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
- void updateParent(const sp<Layer>& parentLayer);
-
private:
// ISurfaceComposerClient interface
virtual status_t createSurface(
@@ -68,17 +65,11 @@
virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
- virtual status_t onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-
- sp<Layer> getParentLayer(bool* outParentDied = nullptr) const;
-
// constant
sp<SurfaceFlinger> mFlinger;
// protected by mLock
DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
- wp<Layer> mParentLayer;
// thread-safe
mutable Mutex mLock;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0497571..168b27c 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -98,6 +98,10 @@
bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
HWC2::DisplayCapability capability) const {
if (!displayId) {
+ // Checkout global capabilities for displays without a corresponding HWC display.
+ if (capability == HWC2::DisplayCapability::SkipClientColorTransform) {
+ return hasCapability(HWC2::Capability::SkipClientColorTransform);
+ }
return false;
}
RETURN_IF_INVALID_DISPLAY(*displayId, false);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f4b3cdd..2d3fd8e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1666,11 +1666,6 @@
}
for (const sp<Layer>& child : mCurrentChildren) {
newParent->addChild(child);
-
- sp<Client> client(child->mClientRef.promote());
- if (client != nullptr) {
- client->updateParent(newParent);
- }
}
mCurrentChildren.clear();
@@ -1705,13 +1700,6 @@
addToCurrentState();
}
- sp<Client> client(mClientRef.promote());
- sp<Client> newParentClient(newParent->mClientRef.promote());
-
- if (client != newParentClient) {
- client->updateParent(newParent);
- }
-
Mutex::Autolock lock(mStateMutex);
if (mLayerDetached) {
mLayerDetached = false;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 02cd9d9..13997be 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -458,19 +458,6 @@
return initClient(new Client(this));
}
-sp<ISurfaceComposerClient> SurfaceFlinger::createScopedConnection(
- const sp<IGraphicBufferProducer>& gbp) {
- if (authenticateSurfaceTexture(gbp) == false) {
- return nullptr;
- }
- const auto& layer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
- if (layer == nullptr) {
- return nullptr;
- }
-
- return initClient(new Client(this, layer));
-}
-
sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
bool secure)
{
@@ -3243,7 +3230,8 @@
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc,
- const sp<Layer>& parent)
+ const sp<Layer>& parent,
+ bool addToCurrentState)
{
// add this layer to the current state list
{
@@ -3253,13 +3241,12 @@
MAX_LAYERS);
return NO_MEMORY;
}
- if (parent == nullptr) {
+ if (parent == nullptr && addToCurrentState) {
mCurrentState.layersSortedByZ.add(lbc);
- } else {
- if (parent->isRemovedFromCurrentState()) {
+ } else if (parent == nullptr || parent->isRemovedFromCurrentState()) {
ALOGE("addClientLayer called with a removed parent");
lbc->onRemovedFromCurrentState();
- }
+ } else {
parent->addChild(lbc);
}
@@ -3337,7 +3324,7 @@
if (composerStateContainsUnsignaledFences(states)) {
break;
}
- applyTransactionState(states, displays, flags);
+ applyTransactionState(states, displays, flags, mInputWindowCommands);
transactionQueue.pop();
}
@@ -3383,7 +3370,8 @@
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken) {
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands) {
ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
@@ -3399,11 +3387,12 @@
return;
}
- applyTransactionState(states, displays, flags);
+ applyTransactionState(states, displays, flags, inputWindowCommands);
}
void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
- const Vector<DisplayState>& displays, uint32_t flags) {
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const InputWindowCommands& inputWindowCommands) {
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
@@ -3444,6 +3433,8 @@
setDestroyStateLocked(state);
}
+ transactionFlags |= addInputWindowCommands(inputWindowCommands);
+
// If a synchronous transaction is explicitly requested without any changes, force a transaction
// anyway. This can be used as a flush mechanism for previous async transactions.
// Empty animation transaction can be used to simulate back-pressure, so also force a
@@ -3781,6 +3772,16 @@
}
}
+uint32_t SurfaceFlinger::addInputWindowCommands(const InputWindowCommands& inputWindowCommands) {
+ uint32_t flags = 0;
+ if (!inputWindowCommands.transferTouchFocusCommands.empty()) {
+ flags |= eTraversalNeeded;
+ }
+
+ mInputWindowCommands.merge(inputWindowCommands);
+ return flags;
+}
+
status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
@@ -3850,7 +3851,9 @@
layer->setInfo(windowType, ownerUid);
- result = addClientLayer(client, *handle, *gbp, layer, *parent);
+ bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
+ result = addClientLayer(client, *handle, *gbp, layer, *parent,
+ addToCurrentState);
if (result != NO_ERROR) {
return result;
}
@@ -3995,7 +3998,7 @@
d.width = 0;
d.height = 0;
displays.add(d);
- setTransactionState(state, displays, 0, nullptr);
+ setTransactionState(state, displays, 0, nullptr, mInputWindowCommands);
const auto display = getDisplayDevice(displayToken);
if (!display) return;
@@ -4814,7 +4817,6 @@
// access to SF.
case BOOT_FINISHED:
case CLEAR_ANIMATION_FRAME_STATS:
- case CREATE_CONNECTION:
case CREATE_DISPLAY:
case DESTROY_DISPLAY:
case ENABLE_VSYNC_INJECTIONS:
@@ -4861,8 +4863,7 @@
// Calling setTransactionState is safe, because you need to have been
// granted a reference to Client* and Handle* to do anything with it.
case SET_TRANSACTION_STATE:
- // Creating a scoped connection is safe, as per discussion in ISurfaceComposer.h
- case CREATE_SCOPED_CONNECTION:
+ case CREATE_CONNECTION:
case GET_COLOR_MANAGEMENT:
case GET_COMPOSITION_PREFERENCE: {
return OK;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 822bb18..bfc87a0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -437,13 +437,13 @@
* ISurfaceComposer interface
*/
virtual sp<ISurfaceComposerClient> createConnection();
- virtual sp<ISurfaceComposerClient> createScopedConnection(const sp<IGraphicBufferProducer>& gbp);
virtual sp<IBinder> createDisplay(const String8& displayName, bool secure);
virtual void destroyDisplay(const sp<IBinder>& displayToken);
virtual sp<IBinder> getBuiltInDisplay(int32_t id);
virtual void setTransactionState(const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken);
+ const sp<IBinder>& applyToken,
+ const InputWindowCommands& inputWindowCommands);
virtual void bootFinished();
virtual bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -555,8 +555,8 @@
* Transactions
*/
void applyTransactionState(const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays, uint32_t flags)
- REQUIRES(mStateLock);
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const InputWindowCommands& inputWindowCommands) REQUIRES(mStateLock);
bool flushTransactionQueues();
uint32_t getTransactionFlags(uint32_t flags);
uint32_t peekTransactionFlags();
@@ -570,6 +570,7 @@
uint32_t setClientStateLocked(const ComposerState& composerState);
uint32_t setDisplayStateLocked(const DisplayState& s);
void setDestroyStateLocked(const ComposerState& composerState);
+ uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
/* ------------------------------------------------------------------------
* Layer management
@@ -618,7 +619,8 @@
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc,
- const sp<Layer>& parent);
+ const sp<Layer>& parent,
+ bool addToCurrentState);
/* ------------------------------------------------------------------------
* Boot animation, on/off animations and screen capture
@@ -1020,6 +1022,8 @@
sp<Scheduler::ConnectionHandle> mSfConnectionHandle;
sp<IInputFlinger> mInputFlinger;
+
+ InputWindowCommands mInputWindowCommands;
};
}; // namespace android
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index a73ec6c..8560f5e 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -162,10 +162,10 @@
setSystemUID();
ASSERT_NO_FATAL_FAILURE(initClient());
- // No one else can init the client.
+ // Anyone else can init the client.
setBinUID();
mComposerClient = new SurfaceComposerClient;
- ASSERT_EQ(NO_INIT, mComposerClient->initCheck());
+ ASSERT_NO_FATAL_FAILURE(initClient());
}
TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) {
@@ -222,22 +222,6 @@
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
}
-TEST_F(CredentialsTest, CreateSurfaceTest) {
- sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- DisplayInfo info;
- SurfaceComposerClient::getDisplayInfo(display, &info);
- const ssize_t displayWidth = info.w;
- const ssize_t displayHeight = info.h;
-
- std::function<bool()> condition = [=]() {
- mBGSurfaceControl =
- mComposerClient->createSurface(SURFACE_NAME, displayWidth, displayHeight,
- PIXEL_FORMAT_RGBA_8888, 0);
- return mBGSurfaceControl != nullptr && mBGSurfaceControl->isValid();
- };
- ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
-}
-
TEST_F(CredentialsTest, CreateDisplayTest) {
std::function<bool()> condition = [=]() {
sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, true);