Merge "Don't invoke transactions on layers that will be removed."
diff --git a/cmds/flatland/Android.mk b/cmds/flatland/Android.mk
index c295167..7aa111c 100644
--- a/cmds/flatland/Android.mk
+++ b/cmds/flatland/Android.mk
@@ -8,6 +8,8 @@
Renderers.cpp \
Main.cpp \
+LOCAL_CFLAGS := -Wall -Werror
+
LOCAL_MODULE:= flatland
LOCAL_MODULE_TAGS := tests
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index ec1e543..3d7cac0 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -284,7 +284,6 @@
public:
Layer() :
- mFirstFrame(true),
mGLHelper(NULL),
mSurface(EGL_NO_SURFACE) {
}
@@ -358,8 +357,6 @@
}
private:
- bool mFirstFrame;
-
LayerDesc mDesc;
GLHelper* mGLHelper;
@@ -389,7 +386,6 @@
ATRACE_CALL();
bool result;
- EGLint resulte;
float scaleFactor = float(mDesc.runHeights[mInstance]) /
float(mDesc.height);
@@ -465,7 +461,6 @@
ATRACE_CALL();
bool result;
- status_t err;
resetColorGenerator();
diff --git a/cmds/ip-up-vpn/Android.mk b/cmds/ip-up-vpn/Android.mk
index 36bbdf5..e1e2204 100644
--- a/cmds/ip-up-vpn/Android.mk
+++ b/cmds/ip-up-vpn/Android.mk
@@ -18,6 +18,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := ip-up-vpn.c
+LOCAL_CFLAGS := -Wall -Werror
LOCAL_SHARED_LIBRARIES := libcutils liblog
LOCAL_MODULE := ip-up-vpn
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/ppp
diff --git a/cmds/rawbu/Android.mk b/cmds/rawbu/Android.mk
index b580390..9322151 100644
--- a/cmds/rawbu/Android.mk
+++ b/cmds/rawbu/Android.mk
@@ -5,6 +5,8 @@
LOCAL_SRC_FILES:= backup.cpp
+LOCAL_CFLAGS := -Wall -Werror
+
LOCAL_SHARED_LIBRARIES := libcutils libc
LOCAL_MODULE:= rawbu
diff --git a/cmds/rawbu/backup.cpp b/cmds/rawbu/backup.cpp
index ff6719f..0072281 100644
--- a/cmds/rawbu/backup.cpp
+++ b/cmds/rawbu/backup.cpp
@@ -129,7 +129,6 @@
}
if(S_ISDIR(statBuffer.st_mode)) {
- int i;
char *newpath;
newpath = strdup(nameBuffer);
diff --git a/cmds/surfacereplayer/proto/Android.bp b/cmds/surfacereplayer/proto/Android.bp
index dda80bb..71a5e23 100644
--- a/cmds/surfacereplayer/proto/Android.bp
+++ b/cmds/surfacereplayer/proto/Android.bp
@@ -3,6 +3,10 @@
srcs: [
"src/trace.proto",
],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
proto: {
type: "lite",
export_proto_headers: true,
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 3c99f99..a5cf9ae 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -33,6 +33,7 @@
const int kUsage = 0;
const uint64_t kContext = 42;
const size_t kMaxConsumerCount = 63;
+const int kPollTimeoutMs = 100;
using LibBufferHubTest = ::testing::Test;
@@ -51,51 +52,51 @@
// Producer state mask is unique, i.e. 1.
EXPECT_EQ(p->buffer_state_bit(), kProducerStateBit);
// Consumer state mask cannot have producer bit on.
- EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0);
+ EXPECT_EQ(c->buffer_state_bit() & kProducerStateBit, 0U);
// Consumer state mask must be a single, i.e. power of 2.
- EXPECT_NE(c->buffer_state_bit(), 0);
- EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0);
+ EXPECT_NE(c->buffer_state_bit(), 0U);
+ EXPECT_EQ(c->buffer_state_bit() & (c->buffer_state_bit() - 1), 0U);
// Consumer state mask cannot have producer bit on.
- EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0);
+ EXPECT_EQ(c2->buffer_state_bit() & kProducerStateBit, 0U);
// Consumer state mask must be a single, i.e. power of 2.
- EXPECT_NE(c2->buffer_state_bit(), 0);
- EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0);
+ EXPECT_NE(c2->buffer_state_bit(), 0U);
+ EXPECT_EQ(c2->buffer_state_bit() & (c2->buffer_state_bit() - 1), 0U);
// Each consumer should have unique bit.
- EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0);
+ EXPECT_EQ(c->buffer_state_bit() & c2->buffer_state_bit(), 0U);
// Initial state: producer not available, consumers not available.
- EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
- EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
- EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
+ EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
// New state: producer not available, consumers available.
- EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
- EXPECT_EQ(1, RETRY_EINTR(c->Poll(100)));
- EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
+ EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(1, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
uint64_t context;
LocalHandle fence;
EXPECT_EQ(0, c->Acquire(&fence, &context));
EXPECT_EQ(kContext, context);
- EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
- EXPECT_EQ(1, RETRY_EINTR(c2->Poll(100)));
+ EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(1, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c2->Acquire(&fence, &context));
EXPECT_EQ(kContext, context);
- EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
- EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
+ EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c->Release(LocalHandle()));
- EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
+ EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c2->Discard());
- EXPECT_EQ(1, RETRY_EINTR(p->Poll(100)));
+ EXPECT_EQ(1, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, p->Gain(&fence));
- EXPECT_EQ(0, RETRY_EINTR(p->Poll(100)));
- EXPECT_EQ(0, RETRY_EINTR(c->Poll(100)));
- EXPECT_EQ(0, RETRY_EINTR(c2->Poll(100)));
+ EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
+ EXPECT_EQ(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
}
TEST_F(LibBufferHubTest, TestEpoll) {
@@ -137,7 +138,8 @@
// Post the producer and check for consumer signal.
EXPECT_EQ(0, p->Post({}, kContext));
- ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
+ ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+ kPollTimeoutMs));
ASSERT_TRUE(events[0].events & EPOLLIN);
ASSERT_EQ(c->event_fd(), events[0].data.fd);
@@ -145,10 +147,14 @@
event = events[0];
// Check for events again. Edge-triggered mode should prevent any.
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
+ EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+ kPollTimeoutMs));
+ EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+ kPollTimeoutMs));
+ EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+ kPollTimeoutMs));
+ EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+ kPollTimeoutMs));
// Translate the events.
auto event_status = c->GetEventMask(event.events);
@@ -156,7 +162,8 @@
ASSERT_TRUE(event_status.get() & EPOLLIN);
// Check for events again. Edge-triggered mode should prevent any.
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 100));
+ EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
+ kPollTimeoutMs));
}
TEST_F(LibBufferHubTest, TestStateMask) {
@@ -171,7 +178,7 @@
cs[i] = BufferConsumer::Import(p->CreateConsumer());
ASSERT_TRUE(cs[i].get() != nullptr);
// Expect all buffers have unique state mask.
- EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0);
+ EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
buffer_state_bits |= cs[i]->buffer_state_bit();
}
EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
@@ -187,7 +194,7 @@
cs[i] = BufferConsumer::Import(p->CreateConsumer());
ASSERT_TRUE(cs[i].get() != nullptr);
// The released state mask will be reused.
- EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0);
+ EXPECT_EQ(buffer_state_bits & cs[i]->buffer_state_bit(), 0U);
buffer_state_bits |= cs[i]->buffer_state_bit();
EXPECT_EQ(buffer_state_bits, kProducerStateBit | kConsumerStateMask);
}
@@ -229,7 +236,7 @@
// Release in acquired state should succeed.
EXPECT_EQ(0, c->Release(LocalHandle()));
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
// Release, acquire, and post in released state should fail.
EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
@@ -277,7 +284,7 @@
EXPECT_FALSE(invalid_fence.IsValid());
// Acquire in posted state should succeed.
- EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
EXPECT_FALSE(invalid_fence.IsValid());
EXPECT_EQ(p->buffer_state(), c->buffer_state());
@@ -292,7 +299,7 @@
// Release in acquired state should succeed.
EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_EQ(p->buffer_state(), c->buffer_state());
EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
@@ -330,7 +337,7 @@
EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
// The buffer should stay in posted stay until a consumer picks it up.
- EXPECT_GE(0, RETRY_EINTR(p->Poll(100)));
+ EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
// A new consumer should still be able to acquire the buffer immediately.
std::unique_ptr<BufferConsumer> c =
@@ -361,7 +368,7 @@
for (size_t i = 0; i < kMaxConsumerCount; i++) {
EXPECT_TRUE(IsBufferPosted(cs[i]->buffer_state(),
cs[i]->buffer_state_bit()));
- EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(cs[i]->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
EXPECT_TRUE(IsBufferAcquired(p->buffer_state()));
}
@@ -373,7 +380,7 @@
EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
}
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
// Buffer state cross all clients must be consistent.
@@ -399,7 +406,7 @@
// Post the gained buffer should signal already created consumer.
EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
EXPECT_TRUE(IsBufferPosted(p->buffer_state()));
- EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
EXPECT_TRUE(IsBufferAcquired(c->buffer_state()));
}
@@ -440,7 +447,7 @@
// Post, acquire, and release the buffer..
EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_LT(0, RETRY_EINTR(c1->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
@@ -450,7 +457,7 @@
BufferConsumer::Import(p->CreateConsumer());
ASSERT_TRUE(c2.get() != nullptr);
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
EXPECT_TRUE(IsBufferGained(p->buffer_state()));
@@ -470,7 +477,7 @@
Metadata m = {1, 3};
EXPECT_EQ(0, p->Post(LocalHandle(), m));
- EXPECT_LE(0, RETRY_EINTR(c->Poll(10)));
+ EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
LocalHandle fence;
Metadata m2 = {};
@@ -503,7 +510,7 @@
// buffer allocation.
OverSizedMetadata evil_meta = {};
EXPECT_NE(0, p->Post(LocalHandle(), evil_meta));
- EXPECT_GE(0, RETRY_EINTR(c->Poll(10)));
+ EXPECT_GE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
// It is ok to post metadata smaller than originally requested during
// buffer allocation.
@@ -638,7 +645,7 @@
EXPECT_EQ(0, p->Post<void>(LocalHandle()));
EXPECT_EQ(0, c->Acquire(&fence));
EXPECT_EQ(0, c->Release(LocalHandle()));
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
// Test that removing persistence and closing the producer orphans the
// consumer.
@@ -679,7 +686,7 @@
// Should acquire a valid fence.
LocalHandle f2;
- EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
EXPECT_TRUE(f2.IsValid());
// The original fence and acquired fence should have different fd number.
@@ -689,14 +696,14 @@
// Signal the original fence will trigger the new fence.
eventfd_write(f1.Get(), 1);
// Now the original FD has been signaled.
- EXPECT_LT(0, PollFd(f2.Get(), 10));
+ EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
// Release the consumer with an invalid fence.
EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
// Should gain an invalid fence.
LocalHandle f3;
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, p->GainAsync(&meta, &f3));
EXPECT_FALSE(f3.IsValid());
@@ -705,10 +712,10 @@
// Should acquire a valid fence and it's already signalled.
LocalHandle f4;
- EXPECT_LT(0, RETRY_EINTR(c->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
EXPECT_TRUE(f4.IsValid());
- EXPECT_LT(0, PollFd(f4.Get(), 10));
+ EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
// Release with an unsignalled fence and signal it immediately after release
// without producer gainning.
@@ -718,10 +725,10 @@
// Should gain a valid fence, which is already signaled.
LocalHandle f6;
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
EXPECT_EQ(0, p->GainAsync(&meta, &f6));
EXPECT_TRUE(f6.IsValid());
- EXPECT_LT(0, PollFd(f6.Get(), 10));
+ EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
}
TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
@@ -737,12 +744,12 @@
EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
LocalHandle fence;
- EXPECT_LT(0, RETRY_EINTR(c1->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c1->Poll(kPollTimeoutMs)));
EXPECT_LE(0, c1->AcquireAsync(&meta, &fence));
// Destroy the consumer now will make it orphaned and the buffer is still
// acquired.
c1 = nullptr;
- EXPECT_GE(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_GE(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
std::unique_ptr<BufferConsumer> c2 =
BufferConsumer::Import(p->CreateConsumer());
@@ -751,13 +758,13 @@
EXPECT_NE(consumer_state_bit1, consumer_state_bit2);
// The new consumer is available for acquire.
- EXPECT_LT(0, RETRY_EINTR(c2->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(c2->Poll(kPollTimeoutMs)));
EXPECT_LE(0, c2->AcquireAsync(&meta, &fence));
// Releasing the consumer makes the buffer gainable.
EXPECT_EQ(0, c2->ReleaseAsync(&meta, LocalHandle()));
// The buffer is now available for the producer to gain.
- EXPECT_LT(0, RETRY_EINTR(p->Poll(10)));
+ EXPECT_LT(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
// But if another consumer is created in released state.
std::unique_ptr<BufferConsumer> c3 =
@@ -766,7 +773,7 @@
const uint64_t consumer_state_bit3 = c3->buffer_state_bit();
EXPECT_NE(consumer_state_bit2, consumer_state_bit3);
// The consumer buffer is not acquirable.
- EXPECT_GE(0, RETRY_EINTR(c3->Poll(10)));
+ EXPECT_GE(0, RETRY_EINTR(c3->Poll(kPollTimeoutMs)));
EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &fence));
// Producer should be able to gain no matter what.
diff --git a/libs/vr/libpdx_uds/private/uds/channel_event_set.h b/libs/vr/libpdx_uds/private/uds/channel_event_set.h
index 99e7502..e960740 100644
--- a/libs/vr/libpdx_uds/private/uds/channel_event_set.h
+++ b/libs/vr/libpdx_uds/private/uds/channel_event_set.h
@@ -54,6 +54,14 @@
BorrowedHandle pollhup_event_fd() const { return pollhup_event_fd_.Borrow(); }
BorrowedHandle data_fd() const { return data_fd_.Borrow(); }
+ // Moves file descriptors out of ChannelEventReceiver. Note these operations
+ // immediately invalidates the receiver.
+ std::tuple<LocalHandle, LocalHandle, LocalHandle> TakeFds() {
+ epoll_fd_.Close();
+ return {std::move(data_fd_), std::move(pollin_event_fd_),
+ std::move(pollhup_event_fd_)};
+ }
+
Status<int> GetPendingEvents() const;
Status<int> PollPendingEvents(int timeout_ms) const;
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 32c2d7e..d43c164 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -122,6 +122,16 @@
},
}
+cc_library_static {
+ name: "libEGL_blobCache",
+ defaults: ["egl_libs_defaults"],
+ srcs: [
+ "EGL/BlobCache.cpp",
+ "EGL/FileBlobCache.cpp",
+ ],
+ export_include_dirs: ["EGL"],
+}
+
cc_library_shared {
name: "libEGL",
defaults: ["egl_libs_defaults"],
@@ -133,7 +143,6 @@
"EGL/egl.cpp",
"EGL/eglApi.cpp",
"EGL/Loader.cpp",
- "EGL/BlobCache.cpp",
],
shared_libs: [
"libvndksupport",
@@ -143,7 +152,10 @@
"libhidltransport",
"libutils",
],
- static_libs: ["libEGL_getProcAddress"],
+ static_libs: [
+ "libEGL_getProcAddress",
+ "libEGL_blobCache",
+ ],
ldflags: ["-Wl,--exclude-libs=ALL"],
export_include_dirs: ["EGL/include"],
}
diff --git a/opengl/libs/EGL/BlobCache.cpp b/opengl/libs/EGL/BlobCache.cpp
index 0624b60..b3752f5 100644
--- a/opengl/libs/EGL/BlobCache.cpp
+++ b/opengl/libs/EGL/BlobCache.cpp
@@ -37,9 +37,9 @@
static const uint32_t blobCacheDeviceVersion = 1;
BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize):
+ mMaxTotalSize(maxTotalSize),
mMaxKeySize(maxKeySize),
mMaxValueSize(maxValueSize),
- mMaxTotalSize(maxTotalSize),
mTotalSize(0) {
int64_t now = std::chrono::steady_clock::now().time_since_epoch().count();
#ifdef _WIN32
diff --git a/opengl/libs/EGL/BlobCache.h b/opengl/libs/EGL/BlobCache.h
index a0a270a..1f5d535 100644
--- a/opengl/libs/EGL/BlobCache.h
+++ b/opengl/libs/EGL/BlobCache.h
@@ -97,6 +97,14 @@
//
int unflatten(void const* buffer, size_t size);
+protected:
+ // mMaxTotalSize is the maximum size that all cache entries can occupy. This
+ // includes space for both keys and values. When a call to BlobCache::set
+ // would otherwise cause this limit to be exceeded, either the key/value
+ // pair passed to BlobCache::set will not be cached or other cache entries
+ // will be evicted from the cache to make room for the new entry.
+ const size_t mMaxTotalSize;
+
private:
// Copying is disallowed.
BlobCache(const BlobCache&);
@@ -220,13 +228,6 @@
// simply not add the key/value pair to the cache.
const size_t mMaxValueSize;
- // mMaxTotalSize is the maximum size that all cache entries can occupy. This
- // includes space for both keys and values. When a call to BlobCache::set
- // would otherwise cause this limit to be exceeded, either the key/value
- // pair passed to BlobCache::set will not be cached or other cache entries
- // will be evicted from the cache to make room for the new entry.
- const size_t mMaxTotalSize;
-
// mTotalSize is the total combined size of all keys and values currently in
// the cache.
size_t mTotalSize;
diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp
new file mode 100644
index 0000000..ff608a3
--- /dev/null
+++ b/opengl/libs/EGL/FileBlobCache.cpp
@@ -0,0 +1,185 @@
+/*
+ ** Copyright 2017, 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 "FileBlobCache.h"
+
+#include <inttypes.h>
+#include <log/log.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+
+// Cache file header
+static const char* cacheFileMagic = "EGL$";
+static const size_t cacheFileHeaderSize = 8;
+
+namespace android {
+
+static uint32_t crc32c(const uint8_t* buf, size_t len) {
+ const uint32_t polyBits = 0x82F63B78;
+ uint32_t r = 0;
+ for (size_t i = 0; i < len; i++) {
+ r ^= buf[i];
+ for (int j = 0; j < 8; j++) {
+ if (r & 1) {
+ r = (r >> 1) ^ polyBits;
+ } else {
+ r >>= 1;
+ }
+ }
+ }
+ return r;
+}
+
+FileBlobCache::FileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize,
+ const std::string& filename)
+ : BlobCache(maxKeySize, maxValueSize, maxTotalSize)
+ , mFilename(filename) {
+ if (mFilename.length() > 0) {
+ size_t headerSize = cacheFileHeaderSize;
+
+ int fd = open(mFilename.c_str(), O_RDONLY, 0);
+ if (fd == -1) {
+ if (errno != ENOENT) {
+ ALOGE("error opening cache file %s: %s (%d)", mFilename.c_str(),
+ strerror(errno), errno);
+ }
+ return;
+ }
+
+ struct stat statBuf;
+ if (fstat(fd, &statBuf) == -1) {
+ ALOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno);
+ close(fd);
+ return;
+ }
+
+ // Sanity check the size before trying to mmap it.
+ size_t fileSize = statBuf.st_size;
+ if (fileSize > mMaxTotalSize * 2) {
+ ALOGE("cache file is too large: %#" PRIx64,
+ static_cast<off64_t>(statBuf.st_size));
+ close(fd);
+ return;
+ }
+
+ uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize,
+ PROT_READ, MAP_PRIVATE, fd, 0));
+ if (buf == MAP_FAILED) {
+ ALOGE("error mmaping cache file: %s (%d)", strerror(errno),
+ errno);
+ close(fd);
+ return;
+ }
+
+ // Check the file magic and CRC
+ size_t cacheSize = fileSize - headerSize;
+ if (memcmp(buf, cacheFileMagic, 4) != 0) {
+ ALOGE("cache file has bad mojo");
+ close(fd);
+ return;
+ }
+ uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
+ if (crc32c(buf + headerSize, cacheSize) != *crc) {
+ ALOGE("cache file failed CRC check");
+ close(fd);
+ return;
+ }
+
+ int err = unflatten(buf + headerSize, cacheSize);
+ if (err < 0) {
+ ALOGE("error reading cache contents: %s (%d)", strerror(-err),
+ -err);
+ munmap(buf, fileSize);
+ close(fd);
+ return;
+ }
+
+ munmap(buf, fileSize);
+ close(fd);
+ }
+}
+
+void FileBlobCache::writeToFile() {
+ if (mFilename.length() > 0) {
+ size_t cacheSize = getFlattenedSize();
+ size_t headerSize = cacheFileHeaderSize;
+ const char* fname = mFilename.c_str();
+
+ // Try to create the file with no permissions so we can write it
+ // without anyone trying to read it.
+ int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
+ if (fd == -1) {
+ if (errno == EEXIST) {
+ // The file exists, delete it and try again.
+ if (unlink(fname) == -1) {
+ // No point in retrying if the unlink failed.
+ ALOGE("error unlinking cache file %s: %s (%d)", fname,
+ strerror(errno), errno);
+ return;
+ }
+ // Retry now that we've unlinked the file.
+ fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
+ }
+ if (fd == -1) {
+ ALOGE("error creating cache file %s: %s (%d)", fname,
+ strerror(errno), errno);
+ return;
+ }
+ }
+
+ size_t fileSize = headerSize + cacheSize;
+
+ uint8_t* buf = new uint8_t [fileSize];
+ if (!buf) {
+ ALOGE("error allocating buffer for cache contents: %s (%d)",
+ strerror(errno), errno);
+ close(fd);
+ unlink(fname);
+ return;
+ }
+
+ int err = flatten(buf + headerSize, cacheSize);
+ if (err < 0) {
+ ALOGE("error writing cache contents: %s (%d)", strerror(-err),
+ -err);
+ delete [] buf;
+ close(fd);
+ unlink(fname);
+ return;
+ }
+
+ // Write the file magic and CRC
+ memcpy(buf, cacheFileMagic, 4);
+ uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
+ *crc = crc32c(buf + headerSize, cacheSize);
+
+ if (write(fd, buf, fileSize) == -1) {
+ ALOGE("error writing cache file: %s (%d)", strerror(errno),
+ errno);
+ delete [] buf;
+ close(fd);
+ unlink(fname);
+ return;
+ }
+
+ delete [] buf;
+ fchmod(fd, S_IRUSR);
+ close(fd);
+ }
+}
+
+}
\ No newline at end of file
diff --git a/opengl/libs/EGL/FileBlobCache.h b/opengl/libs/EGL/FileBlobCache.h
new file mode 100644
index 0000000..393703f
--- /dev/null
+++ b/opengl/libs/EGL/FileBlobCache.h
@@ -0,0 +1,43 @@
+/*
+ ** Copyright 2017, 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 ANDROID_FILE_BLOB_CACHE_H
+#define ANDROID_FILE_BLOB_CACHE_H
+
+#include "BlobCache.h"
+#include <string>
+
+namespace android {
+
+class FileBlobCache : public BlobCache {
+public:
+ // FileBlobCache attempts to load the saved cache contents from disk into
+ // BlobCache.
+ FileBlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize,
+ const std::string& filename);
+
+ // writeToFile attempts to save the current contents of BlobCache to
+ // disk.
+ void writeToFile();
+
+private:
+ // mFilename is the name of the file for storing cache contents.
+ std::string mFilename;
+};
+
+} // namespace android
+
+#endif // ANDROID_BLOB_CACHE_H
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 579e422..ec548f3 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -20,12 +20,8 @@
#include "egl_display.h"
-
#include <private/EGL/cache.h>
-#include <inttypes.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
#include <unistd.h>
#include <thread>
@@ -37,10 +33,6 @@
static const size_t maxValueSize = 64 * 1024;
static const size_t maxTotalSize = 2 * 1024 * 1024;
-// Cache file header
-static const char* cacheFileMagic = "EGL$";
-static const size_t cacheFileHeaderSize = 8;
-
// The time in seconds to wait before saving newly inserted cache entries.
static const unsigned int deferredSaveDelay = 4;
@@ -124,7 +116,9 @@
void egl_cache_t::terminate() {
std::lock_guard<std::mutex> lock(mMutex);
- saveBlobCacheLocked();
+ if (mBlobCache) {
+ mBlobCache->writeToFile();
+ }
mBlobCache = NULL;
}
@@ -146,8 +140,8 @@
std::thread deferredSaveThread([this]() {
sleep(deferredSaveDelay);
std::lock_guard<std::mutex> lock(mMutex);
- if (mInitialized) {
- saveBlobCacheLocked();
+ if (mInitialized && mBlobCache) {
+ mBlobCache->writeToFile();
}
mSavePending = false;
});
@@ -179,163 +173,11 @@
BlobCache* egl_cache_t::getBlobCacheLocked() {
if (mBlobCache == nullptr) {
- mBlobCache.reset(new BlobCache(maxKeySize, maxValueSize, maxTotalSize));
- loadBlobCacheLocked();
+ mBlobCache.reset(new FileBlobCache(maxKeySize, maxValueSize, maxTotalSize, mFilename));
}
return mBlobCache.get();
}
-static uint32_t crc32c(const uint8_t* buf, size_t len) {
- const uint32_t polyBits = 0x82F63B78;
- uint32_t r = 0;
- for (size_t i = 0; i < len; i++) {
- r ^= buf[i];
- for (int j = 0; j < 8; j++) {
- if (r & 1) {
- r = (r >> 1) ^ polyBits;
- } else {
- r >>= 1;
- }
- }
- }
- return r;
-}
-
-void egl_cache_t::saveBlobCacheLocked() {
- if (mFilename.length() > 0 && mBlobCache != NULL) {
- size_t cacheSize = mBlobCache->getFlattenedSize();
- size_t headerSize = cacheFileHeaderSize;
- const char* fname = mFilename.c_str();
-
- // Try to create the file with no permissions so we can write it
- // without anyone trying to read it.
- int fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
- if (fd == -1) {
- if (errno == EEXIST) {
- // The file exists, delete it and try again.
- if (unlink(fname) == -1) {
- // No point in retrying if the unlink failed.
- ALOGE("error unlinking cache file %s: %s (%d)", fname,
- strerror(errno), errno);
- return;
- }
- // Retry now that we've unlinked the file.
- fd = open(fname, O_CREAT | O_EXCL | O_RDWR, 0);
- }
- if (fd == -1) {
- ALOGE("error creating cache file %s: %s (%d)", fname,
- strerror(errno), errno);
- return;
- }
- }
-
- size_t fileSize = headerSize + cacheSize;
-
- uint8_t* buf = new uint8_t [fileSize];
- if (!buf) {
- ALOGE("error allocating buffer for cache contents: %s (%d)",
- strerror(errno), errno);
- close(fd);
- unlink(fname);
- return;
- }
-
- int err = mBlobCache->flatten(buf + headerSize, cacheSize);
- if (err < 0) {
- ALOGE("error writing cache contents: %s (%d)", strerror(-err),
- -err);
- delete [] buf;
- close(fd);
- unlink(fname);
- return;
- }
-
- // Write the file magic and CRC
- memcpy(buf, cacheFileMagic, 4);
- uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
- *crc = crc32c(buf + headerSize, cacheSize);
-
- if (write(fd, buf, fileSize) == -1) {
- ALOGE("error writing cache file: %s (%d)", strerror(errno),
- errno);
- delete [] buf;
- close(fd);
- unlink(fname);
- return;
- }
-
- delete [] buf;
- fchmod(fd, S_IRUSR);
- close(fd);
- }
-}
-
-void egl_cache_t::loadBlobCacheLocked() {
- if (mFilename.length() > 0) {
- size_t headerSize = cacheFileHeaderSize;
-
- int fd = open(mFilename.c_str(), O_RDONLY, 0);
- if (fd == -1) {
- if (errno != ENOENT) {
- ALOGE("error opening cache file %s: %s (%d)", mFilename.c_str(),
- strerror(errno), errno);
- }
- return;
- }
-
- struct stat statBuf;
- if (fstat(fd, &statBuf) == -1) {
- ALOGE("error stat'ing cache file: %s (%d)", strerror(errno), errno);
- close(fd);
- return;
- }
-
- // Sanity check the size before trying to mmap it.
- size_t fileSize = statBuf.st_size;
- if (fileSize > maxTotalSize * 2) {
- ALOGE("cache file is too large: %#" PRIx64,
- static_cast<off64_t>(statBuf.st_size));
- close(fd);
- return;
- }
-
- uint8_t* buf = reinterpret_cast<uint8_t*>(mmap(NULL, fileSize,
- PROT_READ, MAP_PRIVATE, fd, 0));
- if (buf == MAP_FAILED) {
- ALOGE("error mmaping cache file: %s (%d)", strerror(errno),
- errno);
- close(fd);
- return;
- }
-
- // Check the file magic and CRC
- size_t cacheSize = fileSize - headerSize;
- if (memcmp(buf, cacheFileMagic, 4) != 0) {
- ALOGE("cache file has bad mojo");
- close(fd);
- return;
- }
- uint32_t* crc = reinterpret_cast<uint32_t*>(buf + 4);
- if (crc32c(buf + headerSize, cacheSize) != *crc) {
- ALOGE("cache file failed CRC check");
- close(fd);
- return;
- }
-
- int err = mBlobCache->unflatten(buf + headerSize, cacheSize);
- if (err < 0) {
- ALOGE("error reading cache contents: %s (%d)", strerror(-err),
- -err);
- munmap(buf, fileSize);
- close(fd);
- return;
- }
-
- munmap(buf, fileSize);
- close(fd);
- }
-}
-
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h
index 56360f0..7382b91 100644
--- a/opengl/libs/EGL/egl_cache.h
+++ b/opengl/libs/EGL/egl_cache.h
@@ -20,7 +20,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include "BlobCache.h"
+#include "FileBlobCache.h"
#include <memory>
#include <mutex>
@@ -82,14 +82,6 @@
// possible.
BlobCache* getBlobCacheLocked();
- // saveBlobCache attempts to save the current contents of mBlobCache to
- // disk.
- void saveBlobCacheLocked();
-
- // loadBlobCache attempts to load the saved cache contents from disk into
- // mBlobCache.
- void loadBlobCacheLocked();
-
// mInitialized indicates whether the egl_cache_t is in the initialized
// state. It is initialized to false at construction time, and gets set to
// true when initialize is called. It is set back to false when terminate
@@ -101,7 +93,7 @@
// mBlobCache is the cache in which the key/value blob pairs are stored. It
// is initially NULL, and will be initialized by getBlobCacheLocked the
// first time it's needed.
- std::unique_ptr<BlobCache> mBlobCache;
+ std::unique_ptr<FileBlobCache> mBlobCache;
// mFilename is the name of the file for storing cache contents in between
// program invocations. It is initialized to an empty string at
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 8f5dea2..45093be 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -53,6 +53,7 @@
BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
uint32_t w, uint32_t h, uint32_t flags)
: Layer(flinger, client, name, w, h, flags),
+ mSurfaceFlingerConsumer(nullptr),
mTextureName(-1U),
mFormat(PIXEL_FORMAT_NONE),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
@@ -99,6 +100,18 @@
#endif
}
+void BufferLayer::useSurfaceDamage() {
+ if (mFlinger->mForceFullDamage) {
+ surfaceDamageRegion = Region::INVALID_REGION;
+ } else {
+ surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
+ }
+}
+
+void BufferLayer::useEmptyDamage() {
+ surfaceDamageRegion.clear();
+}
+
bool BufferLayer::isProtected() const {
const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
return (activeBuffer != 0) && (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
@@ -252,6 +265,54 @@
engine.disableTexturing();
}
+#ifdef USE_HWC2
+void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
+ if (mHwcLayers.empty()) {
+ return;
+ }
+ mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
+}
+#else
+void BufferLayer::onLayerDisplayed(const sp<const DisplayDevice>& /*hw*/,
+ HWComposer::HWCLayerInterface* layer) {
+ if (layer) {
+ layer->onDisplayed();
+ mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
+ }
+}
+#endif
+
+void BufferLayer::abandon() {
+ mSurfaceFlingerConsumer->abandon();
+}
+
+bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const {
+ if (mSidebandStreamChanged || mAutoRefresh) {
+ return true;
+ }
+
+ Mutex::Autolock lock(mQueueItemLock);
+ if (mQueueItems.empty()) {
+ return false;
+ }
+ auto timestamp = mQueueItems[0].mTimestamp;
+ nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
+
+ // Ignore timestamps more than a second in the future
+ bool isPlausible = timestamp < (expectedPresent + s2ns(1));
+ ALOGW_IF(!isPlausible,
+ "[%s] Timestamp %" PRId64 " seems implausible "
+ "relative to expectedPresent %" PRId64,
+ mName.string(), timestamp, expectedPresent);
+
+ bool isDue = timestamp < expectedPresent;
+ return isDue || !isPlausible;
+}
+
+void BufferLayer::setTransformHint(uint32_t orientation) const {
+ mSurfaceFlingerConsumer->setTransformHint(orientation);
+}
+
bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
if (mBufferLatched) {
Mutex::Autolock lock(mFrameEventHistoryMutex);
@@ -260,6 +321,60 @@
mRefreshPending = false;
return mQueuedFrames > 0 || mSidebandStreamChanged || mAutoRefresh;
}
+bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
+ const std::shared_ptr<FenceTime>& presentFence,
+ const CompositorTiming& compositorTiming) {
+ // mFrameLatencyNeeded is true when a new frame was latched for the
+ // composition.
+ if (!mFrameLatencyNeeded) return false;
+
+ // Update mFrameEventHistory.
+ {
+ Mutex::Autolock lock(mFrameEventHistoryMutex);
+ mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence,
+ compositorTiming);
+ }
+
+ // Update mFrameTracker.
+ nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
+ mFrameTracker.setDesiredPresentTime(desiredPresentTime);
+
+ std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime();
+ if (frameReadyFence->isValid()) {
+ mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
+ } else {
+ // There was no fence for this frame, so assume that it was ready
+ // to be presented at the desired present time.
+ mFrameTracker.setFrameReadyTime(desiredPresentTime);
+ }
+
+ if (presentFence->isValid()) {
+ mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
+ } else {
+ // The HWC doesn't support present fences, so use the refresh
+ // timestamp instead.
+ mFrameTracker.setActualPresentTime(
+ mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY));
+ }
+
+ mFrameTracker.advanceFrame();
+ mFrameLatencyNeeded = false;
+ return true;
+}
+
+std::vector<OccupancyTracker::Segment> BufferLayer::getOccupancyHistory(bool forceFlush) {
+ std::vector<OccupancyTracker::Segment> history;
+ status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history);
+ if (result != NO_ERROR) {
+ ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result);
+ return {};
+ }
+ return history;
+}
+
+bool BufferLayer::getTransformToDisplayInverse() const {
+ return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
+}
#ifdef USE_HWC2
void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
@@ -485,6 +600,10 @@
return outDirtyRegion;
}
+void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) {
+ mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
+}
+
#ifdef USE_HWC2
void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
// Apply this display's projection's viewport to the visible region
@@ -529,28 +648,6 @@
return;
}
- // SolidColor layers
- if (mActiveBuffer == nullptr) {
- setCompositionType(hwcId, HWC2::Composition::SolidColor);
-
- // For now, we only support black for DimLayer
- error = hwcLayer->setColor({0, 0, 0, 255});
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
-
- // Clear out the transform, because it doesn't make sense absent a
- // source buffer
- error = hwcLayer->setTransform(HWC2::Transform::None);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
-
- return;
- }
-
// Device or Cursor layers
if (mPotentialCursor) {
ALOGV("[%s] Requesting Cursor composition", mName.string());
@@ -580,26 +677,24 @@
}
#else
-void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& hw,
+void BufferLayer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
HWComposer::HWCLayerInterface& layer) {
- // we have to set the visible region on every frame because
- // we currently free it during onLayerDisplayed(), which is called
- // after HWComposer::commit() -- every frame.
- // Apply this display's projection's viewport to the visible region
- // before giving it to the HWC HAL.
- const Transform& tr = hw->getTransform();
- Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
- layer.setVisibleRegionScreen(visible);
- layer.setSurfaceDamage(surfaceDamageRegion);
- mIsGlesComposition = (layer.getCompositionType() == HWC_FRAMEBUFFER);
+ int fenceFd = -1;
- if (mSidebandStream.get()) {
- layer.setSidebandStream(mSidebandStream);
- } else {
- // NOTE: buffer can be NULL if the client never drew into this
- // layer yet, or if we ran out of memory
- layer.setBuffer(mActiveBuffer);
+ // TODO: there is a possible optimization here: we only need to set the
+ // acquire fence the first time a new buffer is acquired on EACH display.
+
+ if (layer.getCompositionType() == HWC_OVERLAY ||
+ layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
+ sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
+ if (fence->isValid()) {
+ fenceFd = fence->dup();
+ if (fenceFd == -1) {
+ ALOGW("failed to dup layer fence, skipping sync: %d", errno);
+ }
+ }
}
+ layer.setAcquireFenceFd(fenceFd);
}
#endif
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 882649b..418f032 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -64,6 +64,12 @@
~BufferLayer() override;
+ // If we have received a new buffer this frame, we will pass its surface
+ // damage down to hardware composer. Otherwise, we must send a region with
+ // one empty rect.
+ void useSurfaceDamage();
+ void useEmptyDamage();
+
// -----------------------------------------------------------------------
// Overriden from Layer
// -----------------------------------------------------------------------
@@ -99,6 +105,23 @@
void onDraw(const RenderArea& renderArea, const Region& clip,
bool useIdentityTransform) const override;
+#ifdef USE_HWC2
+ void onLayerDisplayed(const sp<Fence>& releaseFence) override;
+#else
+ void onLayerDisplayed(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface* layer) override;
+#endif
+
+ void abandon() override;
+ bool shouldPresentNow(const DispSync& dispSync) const override;
+ void setTransformHint(uint32_t orientation) const override;
+ bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
+ const std::shared_ptr<FenceTime>& presentFence,
+ const CompositorTiming& compositorTiming) override;
+ std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
+ bool getTransformToDisplayInverse() const override;
+
+public:
bool onPreComposition(nsecs_t refreshStartTime) override;
#ifdef USE_HWC2
@@ -114,13 +137,15 @@
*/
Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) override;
bool isBufferLatched() const override { return mRefreshPending; }
+ void setDefaultBufferSize(uint32_t w, uint32_t h) override;
#ifdef USE_HWC2
- void setPerFrameData(const sp<const DisplayDevice>& displayDevice);
+ void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
#else
- void setPerFrameData(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer);
+ void setAcquireFence(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface& layer) override;
#endif
+
bool isOpaque(const Layer::State& s) const override;
private:
@@ -160,6 +185,8 @@
sp<IGraphicBufferProducer> getProducer() const;
private:
+ sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
+
// Check all of the local sync points to ensure that all transactions
// which need to have been applied prior to the frame which is about to
// be latched have signaled
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index 500f81f..8a17f88 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -61,6 +61,36 @@
return !isHiddenByPolicy() && s.color.a;
}
+#ifdef USE_HWC2
+void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
+ const Transform& tr = displayDevice->getTransform();
+ const auto& viewport = displayDevice->getViewport();
+ Region visible = tr.transform(visibleRegion.intersect(viewport));
+ auto hwcId = displayDevice->getHwcDisplayId();
+ auto& hwcInfo = mHwcLayers[hwcId];
+ auto& hwcLayer = hwcInfo.layer;
+ auto error = hwcLayer->setVisibleRegion(visible);
+
+ setCompositionType(hwcId, HWC2::Composition::SolidColor);
+
+ half4 color = getColor();
+ error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
+ static_cast<uint8_t>(std::round(255.0f * color.g)),
+ static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
+
+ // Clear out the transform, because it doesn't make sense absent a source buffer
+ error = hwcLayer->setTransform(HWC2::Transform::None);
+ if (error != HWC2::Error::None) {
+ ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(), to_string(error).c_str(),
+ static_cast<int32_t>(error));
+ }
+}
+#endif
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 8901327..debd3c3 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -46,8 +46,29 @@
void releasePendingBuffer(nsecs_t) override {}
#endif
Region latchBuffer(bool&, nsecs_t) override { return Region(); }
+ void useSurfaceDamage() override {}
+ void useEmptyDamage() override {}
bool isBufferLatched() const override { return false; }
bool onPreComposition(nsecs_t) override { return true; }
+ void abandon() override {}
+#ifdef USE_HWC2
+ void setPerFrameData(const sp<const DisplayDevice>& displayDevice) override;
+#else
+ void setAcquireFence(const sp<const DisplayDevice>& /*hw*/,
+ HWComposer::HWCLayerInterface& /*layer*/) override {}
+#endif
+ void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) override {}
+ bool shouldPresentNow(const DispSync& /*dispSync*/) const override { return false; }
+ bool onPostComposition(const std::shared_ptr<FenceTime>& /*glDoneFence*/,
+ const std::shared_ptr<FenceTime>& /*presentFence*/,
+ const CompositorTiming& /*compositorTiming*/) override {
+ return false;
+ }
+ void setTransformHint(uint32_t /*orientation*/) const override {}
+ std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool /*forceFlush*/) override {
+ return {};
+ }
+ bool getTransformToDisplayInverse() const override { return false; }
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 136fbc1..80987a4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -69,7 +69,6 @@
: contentDirty(false),
sequence(uint32_t(android_atomic_inc(&sSequence))),
mFlinger(flinger),
- mSurfaceFlingerConsumer(NULL),
mPremultipliedAlpha(true),
mName(name),
mTransactionFlags(0),
@@ -153,23 +152,16 @@
// callbacks
// ---------------------------------------------------------------------------
+/*
+ * onLayerDisplayed is only meaningful for BufferLayer, but, is called through
+ * Layer. So, the implementation is done in BufferLayer. When called on a
+ * ColorLayer object, it's essentially a NOP.
+ */
#ifdef USE_HWC2
-void Layer::onLayerDisplayed(const sp<Fence>& releaseFence) {
- if (mHwcLayers.empty()) {
- return;
- }
- if (mSurfaceFlingerConsumer) {
- mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
- }
-}
+void Layer::onLayerDisplayed(const sp<Fence>& /*releaseFence*/) {}
#else
void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
- HWComposer::HWCLayerInterface* layer) {
- if (layer) {
- layer->onDisplayed();
- mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence());
- }
-}
+ HWComposer::HWCLayerInterface* /*layer*/) {}
#endif
void Layer::onRemovedFromCurrentState() {
@@ -193,10 +185,8 @@
void Layer::onRemoved() {
// the layer is removed from SF mLayersPendingRemoval
+ abandon();
- if (mSurfaceFlingerConsumer) {
- mSurfaceFlingerConsumer->abandon();
- }
#ifdef USE_HWC2
destroyAllHwcLayers();
#endif
@@ -692,105 +682,9 @@
mHwcLayers[hwcId].forceClientComposition = true;
}
-
-void Layer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
- // Apply this display's projection's viewport to the visible region
- // before giving it to the HWC HAL.
- const Transform& tr = displayDevice->getTransform();
- const auto& viewport = displayDevice->getViewport();
- Region visible = tr.transform(visibleRegion.intersect(viewport));
- auto hwcId = displayDevice->getHwcDisplayId();
- auto& hwcInfo = mHwcLayers[hwcId];
- auto& hwcLayer = hwcInfo.layer;
- auto error = hwcLayer->setVisibleRegion(visible);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- visible.dump(LOG_TAG);
- }
-
- error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- surfaceDamageRegion.dump(LOG_TAG);
- }
-
- // Sideband layers
- if (mSidebandStream.get()) {
- setCompositionType(hwcId, HWC2::Composition::Sideband);
- ALOGV("[%s] Requesting Sideband composition", mName.string());
- error = hwcLayer->setSidebandStream(mSidebandStream->handle());
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
- mSidebandStream->handle(), to_string(error).c_str(), static_cast<int32_t>(error));
- }
- return;
- }
-
- // Client layers
- if (hwcInfo.forceClientComposition ||
- (mActiveBuffer != nullptr && mActiveBuffer->handle == nullptr)) {
- ALOGV("[%s] Requesting Client composition", mName.string());
- setCompositionType(hwcId, HWC2::Composition::Client);
- return;
- }
-
- // SolidColor layers
- if (mActiveBuffer == nullptr) {
- setCompositionType(hwcId, HWC2::Composition::SolidColor);
-
- half4 color = getColor();
- error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
- static_cast<uint8_t>(std::round(255.0f * color.g)),
- static_cast<uint8_t>(std::round(255.0f * color.b)), 255});
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set color: %s (%d)", mName.string(), to_string(error).c_str(),
- static_cast<int32_t>(error));
- }
-
- // Clear out the transform, because it doesn't make sense absent a
- // source buffer
- error = hwcLayer->setTransform(HWC2::Transform::None);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to clear transform: %s (%d)", mName.string(),
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
-
- return;
- }
-
- // Device or Cursor layers
- if (mPotentialCursor) {
- ALOGV("[%s] Requesting Cursor composition", mName.string());
- setCompositionType(hwcId, HWC2::Composition::Cursor);
- } else {
- ALOGV("[%s] Requesting Device composition", mName.string());
- setCompositionType(hwcId, HWC2::Composition::Device);
- }
-
- ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace);
- error = hwcLayer->setDataspace(mCurrentState.dataSpace);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace,
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
-
- uint32_t hwcSlot = 0;
- sp<GraphicBuffer> hwcBuffer;
- hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer, &hwcSlot, &hwcBuffer);
-
- auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
- error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
- if (error != HWC2::Error::None) {
- ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle,
- to_string(error).c_str(), static_cast<int32_t>(error));
- }
-}
-
#else
void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer) {
+ HWComposer::HWCLayerInterface& layer) {
// we have to set the visible region on every frame because
// we currently free it during onLayerDisplayed(), which is called
// after HWComposer::commit() -- every frame.
@@ -812,6 +706,7 @@
}
#endif
+
#ifdef USE_HWC2
void Layer::updateCursorPosition(const sp<const DisplayDevice>& displayDevice) {
auto hwcId = displayDevice->getHwcDisplayId();
@@ -846,26 +741,6 @@
static_cast<int32_t>(error));
}
#else
-void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
- HWComposer::HWCLayerInterface& layer) {
- int fenceFd = -1;
-
- // TODO: there is a possible optimization here: we only need to set the
- // acquire fence the first time a new buffer is acquired on EACH display.
-
- if (layer.getCompositionType() == HWC_OVERLAY ||
- layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
- sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
- if (fence->isValid()) {
- fenceFd = fence->dup();
- if (fenceFd == -1) {
- ALOGW("failed to dup layer fence, skipping sync: %d", errno);
- }
- }
- }
- layer.setAcquireFenceFd(fenceFd);
-}
-
Rect Layer::getPosition(const sp<const DisplayDevice>& hw) {
// this gives us only the "orientation" component of the transform
const State& s(getCurrentState());
@@ -1178,7 +1053,7 @@
const bool sizeChanged = (c.requested.w != s.requested.w) || (c.requested.h != s.requested.h);
- if (mSurfaceFlingerConsumer && sizeChanged) {
+ if (sizeChanged) {
// the size changed, we need to ask our client to request a new buffer
ALOGD_IF(DEBUG_RESIZE,
"doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n"
@@ -1194,7 +1069,7 @@
// record the new size, form this point on, when the client request
// a buffer, it'll get the new size.
- mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w, c.requested.h);
+ setDefaultBufferSize(c.requested.w, c.requested.h);
}
// Don't let Layer::doTransaction update the drawing state
@@ -1529,86 +1404,11 @@
deferTransactionUntil(handle->owner.promote(), frameNumber);
}
-void Layer::useSurfaceDamage() {
- if (mFlinger->mForceFullDamage) {
- surfaceDamageRegion = Region::INVALID_REGION;
- } else {
- surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
- }
-}
-
-void Layer::useEmptyDamage() {
- surfaceDamageRegion.clear();
-}
// ----------------------------------------------------------------------------
// pageflip handling...
// ----------------------------------------------------------------------------
-bool Layer::shouldPresentNow(const DispSync& dispSync) const {
- if (mSidebandStreamChanged || mAutoRefresh) {
- return true;
- }
-
- Mutex::Autolock lock(mQueueItemLock);
- if (mQueueItems.empty()) {
- return false;
- }
- auto timestamp = mQueueItems[0].mTimestamp;
- nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
-
- // Ignore timestamps more than a second in the future
- bool isPlausible = timestamp < (expectedPresent + s2ns(1));
- ALOGW_IF(!isPlausible,
- "[%s] Timestamp %" PRId64 " seems implausible "
- "relative to expectedPresent %" PRId64,
- mName.string(), timestamp, expectedPresent);
-
- bool isDue = timestamp < expectedPresent;
- return isDue || !isPlausible;
-}
-
-bool Layer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
- const std::shared_ptr<FenceTime>& presentFence,
- const CompositorTiming& compositorTiming) {
- // mFrameLatencyNeeded is true when a new frame was latched for the
- // composition.
- if (!mFrameLatencyNeeded) return false;
-
- // Update mFrameEventHistory.
- {
- Mutex::Autolock lock(mFrameEventHistoryMutex);
- mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence, presentFence,
- compositorTiming);
- }
-
- // Update mFrameTracker.
- nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
- mFrameTracker.setDesiredPresentTime(desiredPresentTime);
-
- std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime();
- if (frameReadyFence->isValid()) {
- mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
- } else {
- // There was no fence for this frame, so assume that it was ready
- // to be presented at the desired present time.
- mFrameTracker.setFrameReadyTime(desiredPresentTime);
- }
-
- if (presentFence->isValid()) {
- mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
- } else {
- // The HWC doesn't support present fences, so use the refresh
- // timestamp instead.
- mFrameTracker.setActualPresentTime(
- mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY));
- }
-
- mFrameTracker.advanceFrame();
- mFrameLatencyNeeded = false;
- return true;
-}
-
bool Layer::isHiddenByPolicy() const {
const Layer::State& s(mDrawingState);
const auto& parent = mDrawingParent.promote();
@@ -1643,9 +1443,7 @@
orientation = 0;
}
}
- if (mSurfaceFlingerConsumer) {
- mSurfaceFlingerConsumer->setTransformHint(orientation);
- }
+ setTransformHint(orientation);
}
// ----------------------------------------------------------------------------
@@ -1790,26 +1588,6 @@
}
}
-std::vector<OccupancyTracker::Segment> Layer::getOccupancyHistory(bool forceFlush) {
- std::vector<OccupancyTracker::Segment> history;
-
- if (!mSurfaceFlingerConsumer) return {};
-
- status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history);
- if (result != NO_ERROR) {
- ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result);
- return {};
- }
- return history;
-}
-
-bool Layer::getTransformToDisplayInverse() const {
- if (mSurfaceFlingerConsumer) {
- return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
- }
- return false;
-}
-
size_t Layer::getChildrenCount() const {
size_t count = 0;
for (const sp<Layer>& child : mCurrentChildren) {
@@ -1974,7 +1752,7 @@
LayerVector list = makeTraversalList(stateSet);
int32_t i = 0;
- for (i = list.size() - 1; i >= 0; i--) {
+ for (i = int32_t(list.size()) - 1; i >= 0; i--) {
const auto& relative = list[i];
if (relative->getZ() < 0) {
break;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 3099382..0580b9f 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -42,7 +42,6 @@
#include "LayerVector.h"
#include "MonitoredProducer.h"
#include "SurfaceFlinger.h"
-#include "SurfaceFlingerConsumer.h"
#include "Transform.h"
#include <layerproto/LayerProtoHeader.h>
@@ -230,8 +229,8 @@
// If we have received a new buffer this frame, we will pass its surface
// damage down to hardware composer. Otherwise, we must send a region with
// one empty rect.
- void useSurfaceDamage();
- void useEmptyDamage();
+ virtual void useSurfaceDamage() = 0;
+ virtual void useEmptyDamage() = 0;
uint32_t getTransactionFlags(uint32_t flags);
uint32_t setTransactionFlags(uint32_t flags);
@@ -296,10 +295,12 @@
bool useIdentityTransform) const = 0;
public:
+ virtual void setDefaultBufferSize(uint32_t w, uint32_t h) = 0;
+
#ifdef USE_HWC2
void setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z);
void forceClientComposition(int32_t hwcId);
- void setPerFrameData(const sp<const DisplayDevice>& displayDevice);
+ virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0;
// callIntoHwc exists so we can update our local state and call
// acceptDisplayChanges without unnecessarily updating the device's state
@@ -311,8 +312,8 @@
#else
void setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer);
void setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer);
- void setAcquireFence(const sp<const DisplayDevice>& hw,
- HWComposer::HWCLayerInterface& layer);
+ virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface& layer) = 0;
Rect getPosition(const sp<const DisplayDevice>& hw);
#endif
@@ -320,12 +321,16 @@
* called after page-flip
*/
#ifdef USE_HWC2
- void onLayerDisplayed(const sp<Fence>& releaseFence);
+ virtual void onLayerDisplayed(const sp<Fence>& releaseFence);
#else
- void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer);
+ virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
+ HWComposer::HWCLayerInterface* layer);
#endif
- bool shouldPresentNow(const DispSync& dispSync) const;
+ virtual void abandon() = 0;
+
+ virtual bool shouldPresentNow(const DispSync& dispSync) const = 0;
+ virtual void setTransformHint(uint32_t orientation) const = 0;
/*
* called before composition.
@@ -337,9 +342,9 @@
* called after composition.
* returns true if the layer latched a new buffer this frame.
*/
- bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
- const std::shared_ptr<FenceTime>& presentFence,
- const CompositorTiming& compositorTiming);
+ virtual bool onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
+ const std::shared_ptr<FenceTime>& presentFence,
+ const CompositorTiming& compositorTiming) = 0;
#ifdef USE_HWC2
// If a buffer was replaced this frame, release the former buffer
@@ -463,13 +468,13 @@
void logFrameStats();
void getFrameStats(FrameStats* outStats) const;
- std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush);
+ virtual std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) = 0;
void onDisconnect();
void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
FrameEventHistoryDelta* outDelta);
- bool getTransformToDisplayInverse() const;
+ virtual bool getTransformToDisplayInverse() const = 0;
Transform getTransform() const;
@@ -526,6 +531,7 @@
virtual void onFirstRef();
friend class SurfaceInterceptor;
+
void commitTransaction(const State& stateToCommit);
uint32_t getEffectiveUsage(uint32_t usage) const;
@@ -547,7 +553,6 @@
void addZOrderRelative(const wp<Layer>& relative);
void removeZOrderRelative(const wp<Layer>& relative);
-protected:
class SyncPoint {
public:
explicit SyncPoint(uint64_t frameNumber)
@@ -619,8 +624,6 @@
protected:
// -----------------------------------------------------------------------
- // constants
- sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
bool mPremultipliedAlpha;
String8 mName;
String8 mTransactionName; // A cached version of "TX - " + mName for systraces
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index dded1e3..ade0bde 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -94,7 +94,6 @@
~CreateInfoWrapper();
VkResult Validate();
- void DowngradeApiVersion();
const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
@@ -132,8 +131,6 @@
VkDeviceCreateInfo dev_info_;
};
- VkApplicationInfo application_info_;
-
ExtensionFilter extension_filter_;
std::bitset<ProcHook::EXTENSION_COUNT> hook_extensions_;
@@ -540,15 +537,6 @@
}
}
-void CreateInfoWrapper::DowngradeApiVersion() {
- // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0:
- if (instance_info_.pApplicationInfo) {
- application_info_ = *instance_info_.pApplicationInfo;
- instance_info_.pApplicationInfo = &application_info_;
- application_info_.apiVersion = VK_API_VERSION_1_0;
- }
-}
-
VKAPI_ATTR void* DefaultAllocate(void*,
size_t size,
size_t alignment,
@@ -903,33 +891,6 @@
data->hook_extensions |= wrapper.GetHookExtensions();
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wold-style-cast"
- uint32_t api_version = ((pCreateInfo->pApplicationInfo)
- ? pCreateInfo->pApplicationInfo->apiVersion
- : VK_API_VERSION_1_0);
- uint32_t api_major_version = VK_VERSION_MAJOR(api_version);
- uint32_t api_minor_version = VK_VERSION_MINOR(api_version);
- uint32_t icd_api_version;
- PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
- reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
- Hal::Device().GetInstanceProcAddr(NULL,
- "vkEnumerateInstanceVersion"));
- if (!pfn_enumerate_instance_version) {
- icd_api_version = VK_API_VERSION_1_0;
- } else {
- result = (*pfn_enumerate_instance_version)(&icd_api_version);
- }
- uint32_t icd_api_major_version = VK_VERSION_MAJOR(icd_api_version);
- uint32_t icd_api_minor_version = VK_VERSION_MINOR(icd_api_version);
-
- if ((icd_api_major_version == 1) && (icd_api_minor_version == 0) &&
- ((api_major_version > 1) || (api_minor_version > 0))) {
- api_version = VK_API_VERSION_1_0;
- wrapper.DowngradeApiVersion();
- }
-#pragma clang diagnostic pop
-
// call into the driver
VkInstance instance;
result = Hal::Device().CreateInstance(