Merge "Add glFlush in surfaceflinger screenshot code." into lmp-mr1-dev
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 1fbcef6..526374e 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
@@ -75,6 +76,28 @@
}
}
+static void dump_dev_files(const char *title, const char *driverpath, const char *filename)
+{
+ DIR *d;
+ struct dirent *de;
+ char path[PATH_MAX];
+
+ d = opendir(driverpath);
+ if (d == NULL) {
+ return;
+ }
+
+ while ((de = readdir(d))) {
+ if (de->d_type != DT_LNK) {
+ continue;
+ }
+ snprintf(path, sizeof(path), "%s/%s/%s", driverpath, de->d_name, filename);
+ dump_file(title, path);
+ }
+
+ closedir(d);
+}
+
/* dumps the current system state to stdout */
static void dumpstate() {
time_t now = time(NULL);
@@ -107,6 +130,7 @@
printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
printf("\n");
+ dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
run_command("UPTIME", 10, "uptime", NULL);
dump_file("MEMORY INFO", "/proc/meminfo");
run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-t", NULL);
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index 3fc5de2..c619a11 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -197,6 +197,12 @@
uint32_t mStickyTransform;
+ // This saves the fence from the last queueBuffer, such that the
+ // next queueBuffer call can throttle buffer production. The prior
+ // queueBuffer's fence is not nessessarily available elsewhere,
+ // since the previous buffer might have already been acquired.
+ sp<Fence> mLastQueueBufferFence;
+
}; // class BufferQueueProducer
} // namespace android
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index d2fd3b0..284ddb2 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -38,7 +38,8 @@
mCore(core),
mSlots(core->mSlots),
mConsumerName(),
- mStickyTransform(0) {}
+ mStickyTransform(0),
+ mLastQueueBufferFence(Fence::NO_FENCE) {}
BufferQueueProducer::~BufferQueueProducer() {}
@@ -649,6 +650,15 @@
ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
} // Autolock scope
+ // Wait without lock held
+ if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+ // Waiting here allows for two full buffers to be queued but not a
+ // third. In the event that frames take varying time, this makes a
+ // small trade-off in favor of latency rather than throughput.
+ mLastQueueBufferFence->waitForever("Throttling EGL Production");
+ mLastQueueBufferFence = fence;
+ }
+
// Call back without lock held
if (listener != NULL) {
listener->onFrameAvailable();
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index ccafe81..cc96a92 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -1065,6 +1065,7 @@
if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
ALOGE("~EglImage: eglDestroyImageKHR failed");
}
+ eglTerminate(mEglDisplay);
}
}
@@ -1079,6 +1080,7 @@
if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) {
ALOGE("createIfNeeded: eglDestroyImageKHR failed");
}
+ eglTerminate(mEglDisplay);
mEglImage = EGL_NO_IMAGE_KHR;
mEglDisplay = EGL_NO_DISPLAY;
}
@@ -1129,11 +1131,13 @@
// removes this restriction if there is hardware that can support it.
attrs[2] = EGL_NONE;
}
+ eglInitialize(dpy, 0, 0);
EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs);
if (image == EGL_NO_IMAGE_KHR) {
EGLint error = eglGetError();
ALOGE("error creating EGLImage: %#x", error);
+ eglTerminate(dpy);
}
return image;
}
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 183478d..57e94ef 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -108,17 +108,24 @@
# build surfaceflinger's executable
include $(CLEAR_VARS)
-LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
+LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
+LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" -Iart
+LOCAL_CPPFLAGS:= -std=c++11
+# TODO: Trying to link libsigchain as a static library prevents
+# static linker from exporting necessary symbols. So as a workaround
+# we use sigchain.o
LOCAL_SRC_FILES:= \
- main_surfaceflinger.cpp
+ main_surfaceflinger.cpp \
+ sigchain_proxy.cpp
LOCAL_SHARED_LIBRARIES := \
libsurfaceflinger \
libcutils \
liblog \
libbinder \
- libutils
+ libutils \
+ libdl
LOCAL_MODULE:= surfaceflinger
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index fa07656..f6ad503 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -278,12 +278,17 @@
Rect Layer::computeBounds() const {
const Layer::State& s(getDrawingState());
+ return computeBounds(s.activeTransparentRegion);
+}
+
+Rect Layer::computeBounds(const Region& activeTransparentRegion) const {
+ const Layer::State& s(getDrawingState());
Rect win(s.active.w, s.active.h);
if (!s.active.crop.isEmpty()) {
win.intersect(s.active.crop, &win);
}
// subtract the transparent region and snap to the bounds
- return reduce(win, s.activeTransparentRegion);
+ return reduce(win, activeTransparentRegion);
}
FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
@@ -405,7 +410,22 @@
// apply the layer's transform, followed by the display's global transform
// here we're guaranteed that the layer's transform preserves rects
- Rect frame(s.transform.transform(computeBounds()));
+ Region activeTransparentRegion(s.activeTransparentRegion);
+ if (!s.active.crop.isEmpty()) {
+ Rect activeCrop(s.active.crop);
+ activeCrop = s.transform.transform(activeCrop);
+ activeCrop.intersect(hw->getViewport(), &activeCrop);
+ activeCrop = s.transform.inverse().transform(activeCrop);
+ // mark regions outside the crop as transparent
+ activeTransparentRegion.orSelf(Rect(0, 0, s.active.w, activeCrop.top));
+ activeTransparentRegion.orSelf(Rect(0, activeCrop.bottom,
+ s.active.w, s.active.h));
+ activeTransparentRegion.orSelf(Rect(0, activeCrop.top,
+ activeCrop.left, activeCrop.bottom));
+ activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
+ s.active.w, activeCrop.bottom));
+ }
+ Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
frame.intersect(hw->getViewport(), &frame);
const Transform& tr(hw->getTransform());
layer.setFrame(tr.transform(frame));
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f0fe58a..1f8eff0 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -142,6 +142,7 @@
void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
bool useIdentityTransform) const;
+ Rect computeBounds(const Region& activeTransparentRegion) const;
Rect computeBounds() const;
sp<IBinder> getHandle();
diff --git a/services/surfaceflinger/sigchain_proxy.cpp b/services/surfaceflinger/sigchain_proxy.cpp
new file mode 100644
index 0000000..bb7a678
--- /dev/null
+++ b/services/surfaceflinger/sigchain_proxy.cpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 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 "sigchainlib/sigchain.cc"