Merge "Add API's for normalizing MIME's and URI's."
diff --git a/include/ui/GraphicLog.h b/include/ui/GraphicLog.h
deleted file mode 100644
index ee1b09a..0000000
--- a/include/ui/GraphicLog.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 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_GRAPHIC_LOG_H
-#define _UI_GRAPHIC_LOG_H
-
-#include <utils/Singleton.h>
-#include <cutils/compiler.h>
-
-namespace android {
-
-class GraphicLog : public Singleton<GraphicLog>
-{
- int32_t mEnabled;
- static void logImpl(int32_t tag, int32_t buffer);
- static void logImpl(int32_t tag, int32_t identity, int32_t buffer);
-
-public:
- enum {
- SF_APP_DEQUEUE_BEFORE = 60100,
- SF_APP_DEQUEUE_AFTER = 60101,
- SF_APP_LOCK_BEFORE = 60102,
- SF_APP_LOCK_AFTER = 60103,
- SF_APP_QUEUE = 60104,
-
- SF_REPAINT = 60105,
- SF_COMPOSITION_COMPLETE = 60106,
- SF_UNLOCK_CLIENTS = 60107,
- SF_SWAP_BUFFERS = 60108,
- SF_REPAINT_DONE = 60109,
-
- SF_FB_POST_BEFORE = 60110,
- SF_FB_POST_AFTER = 60111,
- SF_FB_DEQUEUE_BEFORE = 60112,
- SF_FB_DEQUEUE_AFTER = 60113,
- SF_FB_LOCK_BEFORE = 60114,
- SF_FB_LOCK_AFTER = 60115,
- };
-
- inline void log(int32_t tag, int32_t buffer) {
- if (CC_UNLIKELY(mEnabled))
- logImpl(tag, buffer);
- }
- inline void log(int32_t tag, int32_t identity, int32_t buffer) {
- if (CC_UNLIKELY(mEnabled))
- logImpl(tag, identity, buffer);
- }
-
- GraphicLog();
-
- void setEnabled(bool enable);
-};
-
-}
-
-#endif // _UI_GRAPHIC_LOG_H
-
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
index 7b4fb70..1f2c2d5 100644
--- a/include/utils/TypeHelpers.h
+++ b/include/utils/TypeHelpers.h
@@ -233,19 +233,15 @@
}
};
-template<>
template <typename K, typename V>
struct trait_trivial_ctor< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
-template<>
template <typename K, typename V>
struct trait_trivial_dtor< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
-template<>
template <typename K, typename V>
struct trait_trivial_copy< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
-template<>
template <typename K, typename V>
struct trait_trivial_move< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index a42c336..629b899 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -692,7 +692,7 @@
case BR_ACQUIRE_RESULT:
{
- LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
+ ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
@@ -703,7 +703,7 @@
{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
- LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
+ ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
if (err != NO_ERROR) goto finish;
if (reply) {
@@ -752,7 +752,7 @@
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
- LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
+ ALOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
binder_write_read bwr;
@@ -905,7 +905,7 @@
case BR_ACQUIRE:
refs = (RefBase::weakref_type*)mIn.readInt32();
obj = (BBinder*)mIn.readInt32();
- LOG_ASSERT(refs->refBase() == obj,
+ ALOG_ASSERT(refs->refBase() == obj,
"BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
obj->incStrong(mProcess.get());
@@ -921,7 +921,7 @@
case BR_RELEASE:
refs = (RefBase::weakref_type*)mIn.readInt32();
obj = (BBinder*)mIn.readInt32();
- LOG_ASSERT(refs->refBase() == obj,
+ ALOG_ASSERT(refs->refBase() == obj,
"BR_RELEASE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
IF_LOG_REMOTEREFS() {
@@ -946,7 +946,7 @@
// NOTE: This assertion is not valid, because the object may no
// longer exist (thus the (BBinder*)cast above resulting in a different
// memory address).
- //LOG_ASSERT(refs->refBase() == obj,
+ //ALOG_ASSERT(refs->refBase() == obj,
// "BR_DECREFS: object %p does not match cookie %p (expected %p)",
// refs, obj, refs->refBase());
mPendingWeakDerefs.push(refs);
@@ -958,7 +958,7 @@
{
const bool success = refs->attemptIncStrong(mProcess.get());
- LOG_ASSERT(success && refs->refBase() == obj,
+ ALOG_ASSERT(success && refs->refBase() == obj,
"BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
refs, obj, refs->refBase());
@@ -971,7 +971,7 @@
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
- LOG_ASSERT(result == NO_ERROR,
+ ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
@@ -1114,7 +1114,7 @@
IF_LOG_COMMANDS() {
alog << "Writing BC_FREE_BUFFER for " << data << endl;
}
- LOG_ASSERT(data != NULL, "Called with NULL data");
+ ALOG_ASSERT(data != NULL, "Called with NULL data");
if (parcel != NULL) parcel->closeFileDescriptors();
IPCThreadState* state = self();
state->mOut.writeInt32(BC_FREE_BUFFER);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 5ebdbd9..8fe96b1 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -35,15 +35,6 @@
// ---------------------------------------------------------------------------
-/* ideally AID_GRAPHICS would be in a semi-public header
- * or there would be a way to map a user/group name to its id
- */
-#ifndef AID_GRAPHICS
-#define AID_GRAPHICS 1003
-#endif
-
-// ---------------------------------------------------------------------------
-
namespace android {
enum {
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index fbabfc4..f8b4452 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -47,7 +47,6 @@
GraphicBuffer.cpp \
GraphicBufferAllocator.cpp \
GraphicBufferMapper.cpp \
- GraphicLog.cpp \
InputTransport.cpp \
PixelFormat.cpp \
Rect.cpp \
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index f5ed981..d1dca0c 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -29,7 +29,6 @@
#include <ui/Rect.h>
#include <ui/FramebufferNativeWindow.h>
-#include <ui/GraphicLog.h>
#include <EGL/egl.h>
@@ -211,9 +210,6 @@
if (self->mBufferHead >= self->mNumBuffers)
self->mBufferHead = 0;
- GraphicLog& logger(GraphicLog::getInstance());
- logger.log(GraphicLog::SF_FB_DEQUEUE_BEFORE, index);
-
// wait for a free buffer
while (!self->mNumFreeBuffers) {
self->mCondition.wait(self->mutex);
@@ -224,7 +220,6 @@
*buffer = self->buffers[index].get();
- logger.log(GraphicLog::SF_FB_DEQUEUE_AFTER, index);
return 0;
}
@@ -235,16 +230,12 @@
Mutex::Autolock _l(self->mutex);
const int index = self->mCurrentBufferIndex;
- GraphicLog& logger(GraphicLog::getInstance());
- logger.log(GraphicLog::SF_FB_LOCK_BEFORE, index);
// wait that the buffer we're locking is not front anymore
while (self->front == buffer) {
self->mCondition.wait(self->mutex);
}
- logger.log(GraphicLog::SF_FB_LOCK_AFTER, index);
-
return NO_ERROR;
}
@@ -257,13 +248,7 @@
buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
const int index = self->mCurrentBufferIndex;
- GraphicLog& logger(GraphicLog::getInstance());
- logger.log(GraphicLog::SF_FB_POST_BEFORE, index);
-
int res = fb->post(fb, handle);
-
- logger.log(GraphicLog::SF_FB_POST_AFTER, index);
-
self->front = static_cast<NativeBuffer*>(buffer);
self->mNumFreeBuffers++;
self->mCondition.broadcast();
diff --git a/libs/ui/GraphicLog.cpp b/libs/ui/GraphicLog.cpp
deleted file mode 100644
index 7ba2779..0000000
--- a/libs/ui/GraphicLog.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2010 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 <stdlib.h>
-#include <unistd.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include <utils/Endian.h>
-#include <utils/Timers.h>
-
-#include <ui/GraphicLog.h>
-
-namespace android {
-
-ANDROID_SINGLETON_STATIC_INSTANCE(GraphicLog)
-
-static inline
-void writeInt32(uint8_t* base, size_t& pos, int32_t value) {
-#ifdef HAVE_LITTLE_ENDIAN
- int32_t v = value;
-#else
- int32_t v = htole32(value);
-#endif
- base[pos] = EVENT_TYPE_INT;
- memcpy(&base[pos+1], &v, sizeof(int32_t));
- pos += 1+sizeof(int32_t);
-}
-
-static inline
-void writeInt64(uint8_t* base, size_t& pos, int64_t value) {
-#ifdef HAVE_LITTLE_ENDIAN
- int64_t v = value;
-#else
- int64_t v = htole64(value);
-#endif
- base[pos] = EVENT_TYPE_LONG;
- memcpy(&base[pos+1], &v, sizeof(int64_t));
- pos += 1+sizeof(int64_t);
-}
-
-void GraphicLog::logImpl(int32_t tag, int32_t buffer)
-{
- uint8_t scratch[2 + 2 + sizeof(int32_t) + sizeof(int64_t)];
- size_t pos = 0;
- scratch[pos++] = EVENT_TYPE_LIST;
- scratch[pos++] = 2;
- writeInt32(scratch, pos, buffer);
- writeInt64(scratch, pos, ns2ms( systemTime( SYSTEM_TIME_MONOTONIC ) ));
- android_bWriteLog(tag, scratch, sizeof(scratch));
-}
-
-void GraphicLog::logImpl(int32_t tag, int32_t identity, int32_t buffer)
-{
- uint8_t scratch[2 + 3 + sizeof(int32_t) + sizeof(int32_t) + sizeof(int64_t)];
- size_t pos = 0;
- scratch[pos++] = EVENT_TYPE_LIST;
- scratch[pos++] = 3;
- writeInt32(scratch, pos, buffer);
- writeInt32(scratch, pos, identity);
- writeInt64(scratch, pos, ns2ms( systemTime( SYSTEM_TIME_MONOTONIC ) ));
- android_bWriteLog(tag, scratch, sizeof(scratch));
-}
-
-GraphicLog::GraphicLog()
- : mEnabled(0)
-{
- char property[PROPERTY_VALUE_MAX];
- if (property_get("debug.graphic_log", property, NULL) > 0) {
- mEnabled = atoi(property);
- }
-}
-
-void GraphicLog::setEnabled(bool enable)
-{
- mEnabled = enable;
-}
-
-}
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index ad0939e..e80a795 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -332,7 +332,7 @@
refs->addStrongRef(id);
const int32_t c = android_atomic_inc(&refs->mStrong);
- LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
+ ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
#if PRINT_REFS
ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
@@ -352,7 +352,7 @@
#if PRINT_REFS
ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
- LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
+ ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
if (c == 1) {
refs->mBase->onLastStrongRef(id);
if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
@@ -369,7 +369,7 @@
refs->addStrongRef(id);
const int32_t c = android_atomic_inc(&refs->mStrong);
- LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
+ ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow",
refs);
#if PRINT_REFS
ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c);
@@ -399,7 +399,7 @@
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->addWeakRef(id);
const int32_t c = android_atomic_inc(&impl->mWeak);
- LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
+ ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
@@ -408,7 +408,7 @@
weakref_impl* const impl = static_cast<weakref_impl*>(this);
impl->removeWeakRef(id);
const int32_t c = android_atomic_dec(&impl->mWeak);
- LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
+ ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;
if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
@@ -442,7 +442,7 @@
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mStrong;
- LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
+ ALOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow",
this);
while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) {
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) {
@@ -503,7 +503,7 @@
weakref_impl* const impl = static_cast<weakref_impl*>(this);
int32_t curCount = impl->mWeak;
- LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
+ ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow",
this);
while (curCount > 0) {
if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) {
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index 4ce1664..94e072f 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -112,7 +112,7 @@
{
size_t len = strlen16(o);
SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ ALOG_ASSERT(buf, "Unable to allocate shared buffer");
if (buf) {
char16_t* str = (char16_t*)buf->data();
strcpy16(str, o);
@@ -126,7 +126,7 @@
String16::String16(const char16_t* o, size_t len)
{
SharedBuffer* buf = SharedBuffer::alloc((len+1)*sizeof(char16_t));
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ ALOG_ASSERT(buf, "Unable to allocate shared buffer");
if (buf) {
char16_t* str = (char16_t*)buf->data();
memcpy(str, o, len*sizeof(char16_t));
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index 0bc5aff..562f026 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -80,7 +80,7 @@
{
if (len > 0) {
SharedBuffer* buf = SharedBuffer::alloc(len+1);
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ ALOG_ASSERT(buf, "Unable to allocate shared buffer");
if (buf) {
char* str = (char*)buf->data();
memcpy(str, in, len);
@@ -103,7 +103,7 @@
}
SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ ALOG_ASSERT(buf, "Unable to allocate shared buffer");
if (!buf) {
return getEmptyString();
}
@@ -125,7 +125,7 @@
}
SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
- LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ ALOG_ASSERT(buf, "Unable to allocate shared buffer");
if (!buf) {
return getEmptyString();
}
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 4a90296..220ae3e 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -56,7 +56,7 @@
VectorImpl::~VectorImpl()
{
- LOG_ASSERT(!mCount,
+ ALOG_ASSERT(!mCount,
"[%p] "
"subclasses of VectorImpl must call finish_vector()"
" in their destructor. Leaking %d bytes.",
@@ -66,7 +66,7 @@
VectorImpl& VectorImpl::operator = (const VectorImpl& rhs)
{
- LOG_ASSERT(mItemSize == rhs.mItemSize,
+ ALOG_ASSERT(mItemSize == rhs.mItemSize,
"Vector<> have different types (this=%p, rhs=%p)", this, &rhs);
if (this != &rhs) {
release_storage();
@@ -248,7 +248,7 @@
ssize_t VectorImpl::replaceAt(const void* prototype, size_t index)
{
- LOG_ASSERT(index<size(),
+ ALOG_ASSERT(index<size(),
"[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
void* item = editItemLocation(index);
@@ -267,7 +267,7 @@
ssize_t VectorImpl::removeItemsAt(size_t index, size_t count)
{
- LOG_ASSERT((index+count)<=size(),
+ ALOG_ASSERT((index+count)<=size(),
"[%p] remove: index=%d, count=%d, size=%d",
this, (int)index, (int)count, (int)size());
@@ -291,7 +291,7 @@
void* VectorImpl::editItemLocation(size_t index)
{
- LOG_ASSERT(index<capacity(),
+ ALOG_ASSERT(index<capacity(),
"[%p] editItemLocation: index=%d, capacity=%d, count=%d",
this, (int)index, (int)capacity(), (int)mCount);
@@ -303,7 +303,7 @@
const void* VectorImpl::itemLocation(size_t index) const
{
- LOG_ASSERT(index<capacity(),
+ ALOG_ASSERT(index<capacity(),
"[%p] itemLocation: index=%d, capacity=%d, count=%d",
this, (int)index, (int)capacity(), (int)mCount);
@@ -349,7 +349,7 @@
// ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
- LOG_ASSERT(where <= mCount,
+ ALOG_ASSERT(where <= mCount,
"[%p] _grow: where=%d, amount=%d, count=%d",
this, (int)where, (int)amount, (int)mCount); // caller already checked
@@ -402,7 +402,7 @@
// ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
- LOG_ASSERT(where + amount <= mCount,
+ ALOG_ASSERT(where + amount <= mCount,
"[%p] _shrink: where=%d, amount=%d, count=%d",
this, (int)where, (int)amount, (int)mCount); // caller already checked
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 664f258..8b37da5 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -477,6 +477,26 @@
return result;
}
+void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
+ clearError();
+
+ egl_display_t const * const dp = validate_display(dpy);
+ if (!dp) {
+ return;
+ }
+
+ SurfaceRef _s(dp, surface);
+ if (!_s.get()) {
+ setError(EGL_BAD_SURFACE, EGL_FALSE);
+ return;
+ }
+
+ int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+
+ egl_surface_t const * const s = get_surface(surface);
+ native_window_set_buffers_timestamp(s->win.get(), timestamp);
+}
+
// ----------------------------------------------------------------------------
// Contexts
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index 5220aa4..daba3ff 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -107,19 +107,11 @@
fb->add_contents(fbcontents, fbsize);
}
-void fixup_glTexImage2D(GLMessage *glmsg) {
- /* void glTexImage2D(GLenum target,
- GLint level,
- GLint internalformat,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const GLvoid *data);
- */
- GLMessage_DataType arg_width = glmsg->args(3);
- GLMessage_DataType arg_height = glmsg->args(4);
+/** Common fixup routing for glTexImage2D & glTexSubImage2D. */
+void fixup_glTexImage(int widthIndex, int heightIndex, GLMessage *glmsg) {
+ GLMessage_DataType arg_width = glmsg->args(widthIndex);
+ GLMessage_DataType arg_height = glmsg->args(heightIndex);
+
GLMessage_DataType arg_format = glmsg->args(6);
GLMessage_DataType arg_type = glmsg->args(7);
GLMessage_DataType *arg_data = glmsg->mutable_args(8);
@@ -133,21 +125,51 @@
int bytesPerTexel = getBytesPerTexel(format, type);
arg_data->set_type(GLMessage::DataType::BYTE);
- arg_data->set_isarray(true);
arg_data->clear_rawbytes();
if (data != NULL) {
+ arg_data->set_isarray(true);
arg_data->add_rawbytes(data, bytesPerTexel * width * height);
} else {
- ALOGE("fixup_glTexImage2D: image data is NULL.\n");
+ arg_data->set_isarray(false);
arg_data->set_type(GLMessage::DataType::VOID);
- // FIXME:
- // This will create the texture, but it will be uninitialized.
- // It can later be initialized with glTexSubImage2D or by
- // attaching an FBO to it and rendering into the FBO.
}
}
+
+void fixup_glTexImage2D(GLMessage *glmsg) {
+ /* void glTexImage2D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const GLvoid *data);
+ */
+ int widthIndex = 3;
+ int heightIndex = 4;
+ fixup_glTexImage(widthIndex, heightIndex, glmsg);
+}
+
+void fixup_glTexSubImage2D(GLMessage *glmsg) {
+ /*
+ void glTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const GLvoid * data);
+ */
+ int widthIndex = 4;
+ int heightIndex = 5;
+ fixup_glTexImage(widthIndex, heightIndex, glmsg);
+}
+
void fixup_glShaderSource(GLMessage *glmsg) {
/* void glShaderSource(GLuint shader, GLsizei count, const GLchar** string,
const GLint* length) */
@@ -218,6 +240,14 @@
fixup_GenericIntArray(1, n, glmsg);
}
+void fixup_glDeleteGeneric(GLMessage *glmsg) {
+ /* void glDelete*(GLsizei n, GLuint *buffers); */
+ GLMessage_DataType arg_n = glmsg->args(0);
+ GLsizei n = arg_n.intvalue(0);
+
+ fixup_GenericIntArray(1, n, glmsg);
+}
+
void fixup_glGetBooleanv(GLMessage *glmsg) {
/* void glGetBooleanv(GLenum pname, GLboolean *params); */
GLMessage_DataType *arg_params = glmsg->mutable_args(1);
@@ -250,10 +280,16 @@
// do any custom message dependent processing
switch (glmsg->function()) {
- case GLMessage::glGenBuffers: /* void glGenBuffers(GLsizei n, GLuint * buffers); */
- case GLMessage::glGenFramebuffers: /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */
- case GLMessage::glGenRenderbuffers: /* void glGenFramebuffers(GLsizei n, GLuint * buffers); */
- case GLMessage::glGenTextures: /* void glGenTextures(GLsizei n, GLuint * buffers); */
+ case GLMessage::glDeleteBuffers: /* glDeleteBuffers(GLsizei n, GLuint *buffers); */
+ case GLMessage::glDeleteFramebuffers: /* glDeleteFramebuffers(GLsizei n, GLuint *buffers); */
+ case GLMessage::glDeleteRenderbuffers:/* glDeleteRenderbuffers(GLsizei n, GLuint *buffers); */
+ case GLMessage::glDeleteTextures: /* glDeleteTextures(GLsizei n, GLuint *textures); */
+ fixup_glDeleteGeneric(glmsg);
+ break;
+ case GLMessage::glGenBuffers: /* void glGenBuffers(GLsizei n, GLuint *buffers); */
+ case GLMessage::glGenFramebuffers: /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
+ case GLMessage::glGenRenderbuffers: /* void glGenFramebuffers(GLsizei n, GLuint *buffers); */
+ case GLMessage::glGenTextures: /* void glGenTextures(GLsizei n, GLuint *textures); */
fixup_glGenGeneric(glmsg);
break;
case GLMessage::glGetAttribLocation:
@@ -287,6 +323,11 @@
fixup_glTexImage2D(glmsg);
}
break;
+ case GLMessage::glTexSubImage2D:
+ if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) {
+ fixup_glTexSubImage2D(glmsg);
+ }
+ break;
case GLMessage::glShaderSource:
fixup_glShaderSource(glmsg);
break;
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index cf131b1..986aec5 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -350,15 +350,28 @@
}
// this needs to be thread safe
-nsecs_t DisplayHardware::waitForVSync() const {
+nsecs_t DisplayHardware::waitForRefresh() const {
nsecs_t timestamp;
if (mVSync.wait(×tamp) < 0) {
// vsync not supported!
usleep( getDelayToNextVSyncUs(×tamp) );
}
+ mLastHwVSync = timestamp; // FIXME: Not thread safe
return timestamp;
}
+nsecs_t DisplayHardware::getRefreshTimestamp() const {
+ // this returns the last refresh timestamp.
+ // if the last one is not available, we estimate it based on
+ // the refresh period and whatever closest timestamp we have.
+ nsecs_t now = systemTime();
+ return now - ((now - mLastHwVSync) % mRefreshPeriod);
+}
+
+nsecs_t DisplayHardware::getRefreshPeriod() const {
+ return mRefreshPeriod;
+}
+
int32_t DisplayHardware::getDelayToNextVSyncUs(nsecs_t* timestamp) const {
Mutex::Autolock _l(mFakeVSyncMutex);
const nsecs_t period = mRefreshPeriod;
@@ -384,10 +397,6 @@
return mNativeWindow->compositionComplete();
}
-int DisplayHardware::getCurrentBufferIndex() const {
- return mNativeWindow->getCurrentBufferIndex();
-}
-
void DisplayHardware::flip(const Region& dirty) const
{
checkGLErrors();
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index 45d4b45..02be4dc 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -76,7 +76,9 @@
uint32_t getMaxViewportDims() const;
// waits for the next vsync and returns the timestamp of when it happened
- nsecs_t waitForVSync() const;
+ nsecs_t waitForRefresh() const;
+ nsecs_t getRefreshPeriod() const;
+ nsecs_t getRefreshTimestamp() const;
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
@@ -93,9 +95,6 @@
}
inline Rect bounds() const { return getBounds(); }
- // only for debugging
- int getCurrentBufferIndex() const;
-
private:
void init(uint32_t displayIndex) __attribute__((noinline));
void fini() __attribute__((noinline));
@@ -122,6 +121,7 @@
mutable Mutex mFakeVSyncMutex;
mutable nsecs_t mNextFakeVSync;
nsecs_t mRefreshPeriod;
+ mutable nsecs_t mLastHwVSync;
HWComposer* mHwc;
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 9245781..6796d7d 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -102,32 +102,22 @@
nsecs_t timestamp;
DisplayEventReceiver::Event vsync;
- KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > displayEventConnections;
+ Vector< wp<DisplayEventConnection> > displayEventConnections;
{ // scope for the lock
Mutex::Autolock _l(mLock);
do {
- // wait for listeners
+ // see if we need to wait for the VSYNC at all
do {
bool waitForNextVsync = false;
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
const ConnectionInfo& info(
mDisplayEventConnections.valueAt(i));
- if (info.count >= 1) {
- // continuous mode
+ if (info.count >= 0) {
+ // at least one continuous mode or active one-shot event
waitForNextVsync = true;
- } else {
- // one-shot event
- if (info.count >= -1) {
- ConnectionInfo& info(
- mDisplayEventConnections.editValueAt(i));
- info.count--;
- if (info.count == -1) {
- // fired this time around
- waitForNextVsync = true;
- }
- }
+ break;
}
}
@@ -137,51 +127,53 @@
mCondition.wait(mLock);
} while(true);
- // wait for vsync
+ // at least one listener requested VSYNC
mLock.unlock();
- timestamp = mHw.waitForVSync();
+ timestamp = mHw.waitForRefresh();
mLock.lock();
mDeliveredEvents++;
- // make sure we still have some listeners
- } while (!mDisplayEventConnections.size());
+ // now see if we still need to report this VSYNC event
+ bool reportVsync = false;
+ size_t count = mDisplayEventConnections.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const ConnectionInfo& info(
+ mDisplayEventConnections.valueAt(i));
+ if (info.count >= 1) {
+ if (info.count==1 || (mDeliveredEvents % info.count) == 0) {
+ // continuous event, and time to report it
+ reportVsync = true;
+ }
+ } else if (info.count >= -1) {
+ ConnectionInfo& info(
+ mDisplayEventConnections.editValueAt(i));
+ if (info.count == 0) {
+ // fired this time around
+ reportVsync = true;
+ }
+ info.count--;
+ }
+ if (reportVsync) {
+ displayEventConnections.add(mDisplayEventConnections.keyAt(i));
+ }
+ }
+
+ if (reportVsync) {
+ break;
+ }
+ } while (true);
// dispatch vsync events to listeners...
vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
vsync.header.timestamp = timestamp;
vsync.vsync.count = mDeliveredEvents;
-
- // make a copy of our connection list, so we can
- // dispatch events without holding mLock
- displayEventConnections = mDisplayEventConnections;
}
const size_t count = displayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
- sp<DisplayEventConnection> conn(displayEventConnections.keyAt(i).promote());
+ sp<DisplayEventConnection> conn(displayEventConnections[i].promote());
// make sure the connection didn't die
if (conn != NULL) {
-
- const ConnectionInfo& info(
- displayEventConnections.valueAt(i));
-
- if ((info.count > 1) && (mDeliveredEvents % info.count)) {
- // continuous event, but not time to send this event yet
- continue;
- } else if (info.count < -1) {
- // disabled event
- continue;
- } else if (info.count == 0) {
- // impossible by construction. but we prefer to be safe.
- continue;
- }
-
- // here, either:
- // count = -1 : one-shot scheduled this time around
- // count = 1 : continuous not rate-limited
- // count > 1 : continuous, rate-limited
- // Note: count == 0 is not possible by construction
-
status_t err = conn->postEvent(vsync);
if (err == -EAGAIN || err == -EWOULDBLOCK) {
// The destination doesn't accept events anymore, it's probably
@@ -193,12 +185,12 @@
// handle any other error on the pipe as fatal. the only
// reasonable thing to do is to clean-up this connection.
// The most common error we'll get here is -EPIPE.
- removeDisplayEventConnection(displayEventConnections.keyAt(i));
+ removeDisplayEventConnection(displayEventConnections[i]);
}
} else {
// somehow the connection is dead, but we still have it in our list
// just clean the list.
- removeDisplayEventConnection(displayEventConnections.keyAt(i));
+ removeDisplayEventConnection(displayEventConnections[i]);
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d4c4b1f..a294281 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -38,6 +38,7 @@
#include "Layer.h"
#include "SurfaceFlinger.h"
#include "SurfaceTextureLayer.h"
+#include <math.h>
#define DEBUG_RESIZE 0
@@ -54,6 +55,8 @@
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
+ mFrameLatencyNeeded(false),
+ mFrameLatencyOffset(0),
mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
mOpaqueLayer(true),
@@ -65,6 +68,17 @@
glGenTextures(1, &mTextureName);
}
+void Layer::onLayerDisplayed() {
+ if (mFrameLatencyNeeded) {
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
+ mFrameStats[mFrameLatencyOffset].set = systemTime();
+ mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp();
+ mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
+ mFrameLatencyNeeded = false;
+ }
+}
+
void Layer::onFirstRef()
{
LayerBaseClient::onFirstRef();
@@ -408,6 +422,7 @@
// update the active buffer
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
+ mFrameLatencyNeeded = true;
const Rect crop(mSurfaceTexture->getCurrentCrop());
const uint32_t transform(mSurfaceTexture->getCurrentTransform());
@@ -538,11 +553,33 @@
result.append(buffer);
+ LayerBase::dumpStats(result, buffer, SIZE);
+
if (mSurfaceTexture != 0) {
mSurfaceTexture->dump(result, " ", buffer, SIZE);
}
}
+void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
+{
+ LayerBaseClient::dumpStats(result, buffer, SIZE);
+ const size_t o = mFrameLatencyOffset;
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const nsecs_t period = hw.getRefreshPeriod();
+ result.appendFormat("%lld\n", period);
+ for (size_t i=0 ; i<128 ; i++) {
+ const size_t index = (o+i) % 128;
+ const nsecs_t time_app = mFrameStats[index].timestamp;
+ const nsecs_t time_set = mFrameStats[index].set;
+ const nsecs_t time_vsync = mFrameStats[index].vsync;
+ result.appendFormat("%lld\t%lld\t%lld\n",
+ time_app,
+ time_vsync,
+ time_set);
+ }
+ result.append("\n");
+}
+
uint32_t Layer::getEffectiveUsage(uint32_t usage) const
{
// TODO: should we do something special if mSecure is set?
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2b9471b..b3fa5e7 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -34,6 +34,7 @@
#include "LayerBase.h"
#include "SurfaceTextureLayer.h"
#include "Transform.h"
+#include <utils/Timers.h>
namespace android {
@@ -78,12 +79,15 @@
// LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const;
+ virtual void onLayerDisplayed();
+
// only for debugging
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
protected:
virtual void onFirstRef();
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
private:
friend class SurfaceTextureLayer;
@@ -110,6 +114,16 @@
uint32_t mCurrentTransform;
uint32_t mCurrentScalingMode;
bool mCurrentOpacity;
+ bool mFrameLatencyNeeded;
+ int mFrameLatencyOffset;
+ struct Statistics {
+ Statistics() : timestamp(0), set(0), vsync(0) { }
+ nsecs_t timestamp; // buffer timestamp
+ nsecs_t set; // buffer displayed timestamp
+ nsecs_t vsync; // vsync immediately before set
+ };
+ // protected by mLock
+ Statistics mFrameStats[128];
// constants
PixelFormat mFormat;
@@ -121,9 +135,6 @@
bool mSecure; // no screenshots
bool mProtectedByApp; // application requires protected path to external sink
Region mPostedDirtyRegion;
-
- // binder thread, transaction thread
- mutable Mutex mLock;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 37879f1..1e2c4cb 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -471,6 +471,9 @@
void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
{
const Layer::State& s(drawingState());
+ s.transparentRegion.dump(result, "transparentRegion");
+ transparentRegionScreen.dump(result, "transparentRegionScreen");
+ visibleRegionScreen.dump(result, "visibleRegionScreen");
snprintf(buffer, SIZE,
"+ %s %p (%s)\n"
" "
@@ -491,6 +494,9 @@
LayerBase::dump(result, scratch, size);
}
+void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const
+{
+}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 7f62145..03d2cc6 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -205,10 +205,13 @@
/** called with the state lock when the surface is removed from the
* current list */
virtual void onRemoved() { };
-
+
+ virtual void onLayerDisplayed() { };
+
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
virtual void shortDump(String8& result, char* scratch, size_t size) const;
+ virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
enum { // flags for doTransaction()
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bbb30b0..883b642 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -41,7 +41,6 @@
#include <utils/StopWatch.h>
#include <ui/GraphicBufferAllocator.h>
-#include <ui/GraphicLog.h>
#include <ui/PixelFormat.h>
#include <pixelflinger/pixelflinger.h>
@@ -60,15 +59,9 @@
#include "DisplayHardware/DisplayHardware.h"
#include "DisplayHardware/HWComposer.h"
+#include <private/android_filesystem_config.h>
#include <private/surfaceflinger/SharedBufferStack.h>
-/* ideally AID_GRAPHICS would be in a semi-public header
- * or there would be a way to map a user/group name to its id
- */
-#ifndef AID_GRAPHICS
-#define AID_GRAPHICS 1003
-#endif
-
#define EGL_VERSION_HW_ANDROID 0x3143
#define DISPLAY_COUNT 1
@@ -431,25 +424,14 @@
const DisplayHardware& hw(graphicPlane(0).displayHardware());
if (CC_LIKELY(hw.canDraw())) {
// repaint the framebuffer (if needed)
-
- const int index = hw.getCurrentBufferIndex();
- GraphicLog& logger(GraphicLog::getInstance());
-
- logger.log(GraphicLog::SF_REPAINT, index);
handleRepaint();
-
// inform the h/w that we're done compositing
- logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
hw.compositionComplete();
-
- logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
postFramebuffer();
-
- logger.log(GraphicLog::SF_REPAINT_DONE, index);
} else {
// pretend we did the post
hw.compositionComplete();
- hw.waitForVSync();
+ hw.waitForRefresh();
}
return true;
}
@@ -463,6 +445,12 @@
const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;
hw.flip(mSwapRegion);
+
+ size_t numLayers = mVisibleLayersSortedByZ.size();
+ for (size_t i = 0; i < numLayers; i++) {
+ mVisibleLayersSortedByZ[i]->onLayerDisplayed();
+ }
+
mLastSwapBufferTime = systemTime() - now;
mDebugInSwapBuffers = 0;
mSwapRegion.clear();
@@ -1097,23 +1085,6 @@
}
}
-void SurfaceFlinger::debugShowFPS() const
-{
- static int mFrameCount;
- static int mLastFrameCount = 0;
- static nsecs_t mLastFpsTime = 0;
- static float mFps = 0;
- mFrameCount++;
- nsecs_t now = systemTime();
- nsecs_t diff = now - mLastFpsTime;
- if (diff > ms2ns(250)) {
- mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
- mLastFpsTime = now;
- mLastFrameCount = mFrameCount;
- }
- // XXX: mFPS has the value we want
- }
-
status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
{
Mutex::Autolock _l(mStateLock);
@@ -1498,14 +1469,6 @@
IPCThreadState::self()->getCallingUid());
result.append(buffer);
} else {
-
- // figure out if we're stuck somewhere
- const nsecs_t now = systemTime();
- const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
- const nsecs_t inTransaction(mDebugInTransaction);
- nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
- nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
-
// Try to get the main lock, but don't insist if we can't
// (this would indicate SF is stuck, but we want to be able to
// print something in dumpsys).
@@ -1521,111 +1484,20 @@
result.append(buffer);
}
- /*
- * Dump the visible layer list
- */
- const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
- const size_t count = currentLayers.size();
- snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
- result.append(buffer);
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(currentLayers[i]);
- layer->dump(result, buffer, SIZE);
- const Layer::State& s(layer->drawingState());
- s.transparentRegion.dump(result, "transparentRegion");
- layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
- layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
+ bool dumpAll = true;
+ size_t index = 0;
+ if (args.size()) {
+ dumpAll = false;
+ if (args[index] == String16("--latency")) {
+ index++;
+ dumpStatsLocked(args, index, result, buffer, SIZE);
+ }
}
- /*
- * Dump the layers in the purgatory
- */
-
- const size_t purgatorySize = mLayerPurgatory.size();
- snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
- result.append(buffer);
- for (size_t i=0 ; i<purgatorySize ; i++) {
- const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
- layer->shortDump(result, buffer, SIZE);
+ if (dumpAll) {
+ dumpAllLocked(result, buffer, SIZE);
}
- /*
- * Dump SurfaceFlinger global state
- */
-
- snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
- result.append(buffer);
-
- const GLExtensions& extensions(GLExtensions::getInstance());
- snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
- extensions.getVendor(),
- extensions.getRenderer(),
- extensions.getVersion());
- result.append(buffer);
-
- snprintf(buffer, SIZE, "EGL : %s\n",
- eglQueryString(graphicPlane(0).getEGLDisplay(),
- EGL_VERSION_HW_ANDROID));
- result.append(buffer);
-
- snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
- result.append(buffer);
-
- mWormholeRegion.dump(result, "WormholeRegion");
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- snprintf(buffer, SIZE,
- " orientation=%d, canDraw=%d\n",
- mCurrentState.orientation, hw.canDraw());
- result.append(buffer);
- snprintf(buffer, SIZE,
- " last eglSwapBuffers() time: %f us\n"
- " last transaction time : %f us\n"
- " refresh-rate : %f fps\n"
- " x-dpi : %f\n"
- " y-dpi : %f\n",
- mLastSwapBufferTime/1000.0,
- mLastTransactionTime/1000.0,
- hw.getRefreshRate(),
- hw.getDpiX(),
- hw.getDpiY());
- result.append(buffer);
-
- if (inSwapBuffersDuration || !locked) {
- snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
- inSwapBuffersDuration/1000.0);
- result.append(buffer);
- }
-
- if (inTransactionDuration || !locked) {
- snprintf(buffer, SIZE, " transaction time: %f us\n",
- inTransactionDuration/1000.0);
- result.append(buffer);
- }
-
- /*
- * VSYNC state
- */
- mEventThread->dump(result, buffer, SIZE);
-
- /*
- * Dump HWComposer state
- */
- HWComposer& hwc(hw.getHwComposer());
- snprintf(buffer, SIZE, "h/w composer state:\n");
- result.append(buffer);
- snprintf(buffer, SIZE, " h/w composer %s and %s\n",
- hwc.initCheck()==NO_ERROR ? "present" : "not present",
- (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
- result.append(buffer);
- hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
-
- /*
- * Dump gralloc state
- */
- const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
- alloc.dump(result);
- hw.dump(result);
-
if (locked) {
mStateLock.unlock();
}
@@ -1634,6 +1506,137 @@
return NO_ERROR;
}
+void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const
+{
+ String8 name;
+ if (index < args.size()) {
+ name = String8(args[index]);
+ index++;
+ }
+
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ if (name.isEmpty()) {
+ snprintf(buffer, SIZE, "%s\n", layer->getName().string());
+ result.append(buffer);
+ }
+ if (name.isEmpty() || (name == layer->getName())) {
+ layer->dumpStats(result, buffer, SIZE);
+ }
+ }
+}
+
+void SurfaceFlinger::dumpAllLocked(
+ String8& result, char* buffer, size_t SIZE) const
+{
+ // figure out if we're stuck somewhere
+ const nsecs_t now = systemTime();
+ const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
+ const nsecs_t inTransaction(mDebugInTransaction);
+ nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
+ nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
+
+ /*
+ * Dump the visible layer list
+ */
+ const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+ const size_t count = currentLayers.size();
+ snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+ result.append(buffer);
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ layer->dump(result, buffer, SIZE);
+ }
+
+ /*
+ * Dump the layers in the purgatory
+ */
+
+ const size_t purgatorySize = mLayerPurgatory.size();
+ snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+ result.append(buffer);
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ layer->shortDump(result, buffer, SIZE);
+ }
+
+ /*
+ * Dump SurfaceFlinger global state
+ */
+
+ snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
+ result.append(buffer);
+
+ const GLExtensions& extensions(GLExtensions::getInstance());
+ snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
+ extensions.getVendor(),
+ extensions.getRenderer(),
+ extensions.getVersion());
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "EGL : %s\n",
+ eglQueryString(graphicPlane(0).getEGLDisplay(),
+ EGL_VERSION_HW_ANDROID));
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+ result.append(buffer);
+
+ mWormholeRegion.dump(result, "WormholeRegion");
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ snprintf(buffer, SIZE,
+ " orientation=%d, canDraw=%d\n",
+ mCurrentState.orientation, hw.canDraw());
+ result.append(buffer);
+ snprintf(buffer, SIZE,
+ " last eglSwapBuffers() time: %f us\n"
+ " last transaction time : %f us\n"
+ " refresh-rate : %f fps\n"
+ " x-dpi : %f\n"
+ " y-dpi : %f\n",
+ mLastSwapBufferTime/1000.0,
+ mLastTransactionTime/1000.0,
+ hw.getRefreshRate(),
+ hw.getDpiX(),
+ hw.getDpiY());
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n",
+ inSwapBuffersDuration/1000.0);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, " transaction time: %f us\n",
+ inTransactionDuration/1000.0);
+ result.append(buffer);
+
+ /*
+ * VSYNC state
+ */
+ mEventThread->dump(result, buffer, SIZE);
+
+ /*
+ * Dump HWComposer state
+ */
+ HWComposer& hwc(hw.getHwComposer());
+ snprintf(buffer, SIZE, "h/w composer state:\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, " h/w composer %s and %s\n",
+ hwc.initCheck()==NO_ERROR ? "present" : "not present",
+ (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
+ result.append(buffer);
+ hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+
+ /*
+ * Dump gralloc state
+ */
+ const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+ alloc.dump(result);
+ hw.dump(result);
+}
+
status_t SurfaceFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -1707,11 +1710,6 @@
setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
return NO_ERROR;
}
- case 1006:{ // enable/disable GraphicLog
- int enabled = data.readInt32();
- GraphicLog::getInstance().setEnabled(enabled);
- return NO_ERROR;
- }
case 1008: // toggle use of hw composer
n = data.readInt32();
mDebugDisableHWC = n ? 1 : 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ffd3ac9..c976e5a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -335,9 +335,11 @@
status_t electronBeamOnAnimationImplLocked();
void debugFlashRegions();
- void debugShowFPS() const;
void drawWormhole() const;
+ void dumpStatsLocked(const Vector<String16>& args, size_t& index,
+ String8& result, char* buffer, size_t SIZE) const;
+ void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const;
mutable MessageQueue mEventQueue;