Merge "Invoke requestLayout() when drawables have different sizes. Bug #5142668"
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index a6fb12e..493993d 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -275,7 +275,7 @@
enum BufferState {
// FREE indicates that the buffer is not currently being used and
// will not be used in the future until it gets dequeued and
- // subseqently queued by the client.
+ // subsequently queued by the client.
FREE = 0,
// DEQUEUED indicates that the buffer has been dequeued by the
diff --git a/include/utils/String16.h b/include/utils/String16.h
index 584f53f..360f407 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -156,7 +156,7 @@
inline String16 String16::operator+(const String16& other) const
{
- String16 tmp;
+ String16 tmp(*this);
tmp += other;
return tmp;
}
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 7ac4343..ac9b33b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,6 +36,10 @@
#include <utils/Log.h>
#include <utils/String8.h>
+
+#define ALLOW_DEQUEUE_CURRENT_BUFFER false
+
+
namespace android {
// Transform matrices
@@ -294,9 +298,22 @@
if (state == BufferSlot::DEQUEUED) {
dequeuedCount++;
}
- if (state == BufferSlot::FREE /*|| i == mCurrentTexture*/) {
- foundSync = i;
- if (i != mCurrentTexture) {
+
+ // if buffer is FREE it CANNOT be current
+ LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
+ "dequeueBuffer: buffer %d is both FREE and current!", i);
+
+ if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
+ if (state == BufferSlot::FREE || i == mCurrentTexture) {
+ foundSync = i;
+ if (i != mCurrentTexture) {
+ found = i;
+ break;
+ }
+ }
+ } else {
+ if (state == BufferSlot::FREE) {
+ foundSync = i;
found = i;
break;
}
@@ -325,7 +342,7 @@
}
// we're in synchronous mode and didn't find a buffer, we need to wait
- // for for some buffers to be consumed
+ // for some buffers to be consumed
tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
if (tryAgain) {
mDequeueCondition.wait(mMutex);
@@ -482,17 +499,16 @@
mSlots[buf].mScalingMode = mNextScalingMode;
mSlots[buf].mTimestamp = timestamp;
mDequeueCondition.signal();
+
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
} // scope for the lock
// call back without lock held
if (listener != 0) {
listener->onFrameAvailable();
}
-
- *outWidth = mDefaultWidth;
- *outHeight = mDefaultHeight;
- *outTransform = 0;
-
return OK;
}
@@ -847,6 +863,7 @@
void SurfaceTexture::freeAllBuffersLocked() {
LOGW_IF(!mQueue.isEmpty(),
"freeAllBuffersLocked called but mQueue is not empty");
+ mCurrentTexture = INVALID_BUFFER_SLOT;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
freeBufferLocked(i);
}
@@ -860,6 +877,7 @@
Fifo::iterator front(mQueue.begin());
head = *front;
}
+ mCurrentTexture = INVALID_BUFFER_SLOT;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (i != head) {
freeBufferLocked(i);
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 020646b..f24a71d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -24,8 +24,6 @@
#include <EGL/egl.h>
-#include <system/graphics.h>
-
#include <private/ui/android_natives_priv.h>
// ----------------------------------------------------------------------------
@@ -69,49 +67,31 @@
return BAD_VALUE;
// Get all the "potential match" configs...
- if (eglChooseConfig(dpy, attrs, 0, 0, &numConfigs) == EGL_FALSE)
+ if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
- if (numConfigs) {
- EGLConfig* const configs = new EGLConfig[numConfigs];
- if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) {
- delete [] configs;
- return BAD_VALUE;
- }
-
- bool hasAlpha = false;
- switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_RGBA_5551:
- case HAL_PIXEL_FORMAT_RGBA_4444:
- hasAlpha = true;
- break;
- }
-
- // The first config is guaranteed to over-satisfy the constraints
- EGLConfig config = configs[0];
-
- // go through the list and skip configs that over-satisfy our needs
- int i;
- for (i=0 ; i<n ; i++) {
- if (!hasAlpha) {
- EGLint alphaSize;
- eglGetConfigAttrib(dpy, configs[i], EGL_ALPHA_SIZE, &alphaSize);
- if (alphaSize > 0) {
- continue;
- }
- }
+ EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs);
+ if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) {
+ free(configs);
+ return BAD_VALUE;
+ }
+
+ int i;
+ EGLConfig config = NULL;
+ for (i=0 ; i<n ; i++) {
+ EGLint nativeVisualId = 0;
+ eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ if (nativeVisualId>0 && format == nativeVisualId) {
config = configs[i];
break;
}
+ }
- delete [] configs;
-
- if (i<n) {
- *outConfig = config;
- return NO_ERROR;
- }
+ free(configs);
+
+ if (i<n) {
+ *outConfig = config;
+ return NO_ERROR;
}
return NAME_NOT_FOUND;
diff --git a/opengl/tests/swapinterval/swapinterval.cpp b/opengl/tests/swapinterval/swapinterval.cpp
index df53b62..8ca031b 100644
--- a/opengl/tests/swapinterval/swapinterval.cpp
+++ b/opengl/tests/swapinterval/swapinterval.cpp
@@ -48,31 +48,35 @@
EGLNativeWindowType window = android_createDisplaySurface();
dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(dpy, 0 ,0) ;//&majorVersion, &minorVersion);
+ eglInitialize(dpy, &majorVersion, &minorVersion);
eglGetConfigs(dpy, NULL, 0, &numConfigs);
printf("# configs = %d\n", numConfigs);
status_t err = EGLUtils::selectConfigForNativeWindow(
dpy, configAttribs, window, &config);
if (err) {
- fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
+ fprintf(stderr, "error: %s", EGLUtils::strerror(eglGetError()));
+ eglTerminate(dpy);
return 0;
}
- EGLint r,g,b,a;
+ EGLint r,g,b,a, vid;
eglGetConfigAttrib(dpy, config, EGL_RED_SIZE, &r);
eglGetConfigAttrib(dpy, config, EGL_GREEN_SIZE, &g);
eglGetConfigAttrib(dpy, config, EGL_BLUE_SIZE, &b);
eglGetConfigAttrib(dpy, config, EGL_ALPHA_SIZE, &a);
+ eglGetConfigAttrib(dpy, config, EGL_NATIVE_VISUAL_ID, &vid);
surface = eglCreateWindowSurface(dpy, config, window, NULL);
if (surface == EGL_NO_SURFACE) {
EGLint err = eglGetError();
- fprintf(stderr, "%s, config=%p, format = %d-%d-%d-%d\n",
- EGLUtils::strerror(err), config, r,g,b,a);
+ fprintf(stderr, "error: %s, config=%p, format = %d-%d-%d-%d, visual-id = %d\n",
+ EGLUtils::strerror(err), config, r,g,b,a, vid);
+ eglTerminate(dpy);
return 0;
} else {
- printf("config=%p, format = %d-%d-%d-%d\n", config, r,g,b,a);
+ printf("config=%p, format = %d-%d-%d-%d, visual-id = %d\n",
+ config, r,g,b,a, vid);
}
context = eglCreateContext(dpy, config, NULL, NULL);
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index b178e49..51eb0a3 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -5,6 +5,7 @@
Layer.cpp \
LayerBase.cpp \
LayerDim.cpp \
+ DdmConnection.cpp \
DisplayHardware/DisplayHardware.cpp \
DisplayHardware/DisplayHardwareBase.cpp \
DisplayHardware/HWComposer.cpp \
@@ -36,6 +37,9 @@
libui \
libgui
+# this is only needed for DDMS debugging
+LOCAL_SHARED_LIBRARIES += libdvm libandroid_runtime
+
LOCAL_C_INCLUDES := \
$(call include-path-for, corecg graphics)
diff --git a/services/surfaceflinger/DdmConnection.cpp b/services/surfaceflinger/DdmConnection.cpp
new file mode 100644
index 0000000..467a915
--- /dev/null
+++ b/services/surfaceflinger/DdmConnection.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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 <android_runtime/AndroidRuntime.h>
+
+#include "jni.h"
+#include "DdmConnection.h"
+
+extern "C" jint Java_com_android_internal_util_WithFramework_registerNatives(
+ JNIEnv* env, jclass clazz);
+
+namespace android {
+
+void DdmConnection::start(const char* name) {
+ JavaVM* vm;
+ JNIEnv* env;
+
+ // start a VM
+ JavaVMInitArgs args;
+ JavaVMOption opt;
+
+ opt.optionString =
+ "-agentlib:jdwp=transport=dt_android_adb,suspend=n,server=y";
+
+ args.version = JNI_VERSION_1_4;
+ args.options = &opt;
+ args.nOptions = 1;
+ args.ignoreUnrecognized = JNI_FALSE;
+
+ if (JNI_CreateJavaVM(&vm, &env, &args) == 0) {
+ jclass startClass;
+ jmethodID startMeth;
+
+ // register native code
+ if (Java_com_android_internal_util_WithFramework_registerNatives(env, 0) == 0) {
+ // set our name by calling DdmHandleAppName.setAppName()
+ startClass = env->FindClass("android/ddm/DdmHandleAppName");
+ if (startClass) {
+ startMeth = env->GetStaticMethodID(startClass,
+ "setAppName", "(Ljava/lang/String;)V");
+ if (startMeth) {
+ jstring str = env->NewStringUTF(name);
+ env->CallStaticVoidMethod(startClass, startMeth, str);
+ env->DeleteLocalRef(str);
+ }
+ }
+
+ // initialize DDMS communication by calling
+ // DdmRegister.registerHandlers()
+ startClass = env->FindClass("android/ddm/DdmRegister");
+ if (startClass) {
+ startMeth = env->GetStaticMethodID(startClass,
+ "registerHandlers", "()V");
+ if (startMeth) {
+ env->CallStaticVoidMethod(startClass, startMeth);
+ }
+ }
+ }
+ }
+}
+
+}; // namespace android
diff --git a/services/surfaceflinger/DdmConnection.h b/services/surfaceflinger/DdmConnection.h
new file mode 100644
index 0000000..91b737c
--- /dev/null
+++ b/services/surfaceflinger/DdmConnection.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 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_SF_DDM_CONNECTION
+#define ANDROID_SF_DDM_CONNECTION
+
+namespace android {
+
+class DdmConnection {
+public:
+ static void start(const char* name);
+};
+
+}; // namespace android
+
+#endif /* ANDROID_SF_DDM_CONNECTION */
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 082effe..a68ab30 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -47,6 +47,7 @@
#include "clz.h"
#include "GLExtensions.h"
+#include "DdmConnection.h"
#include "Layer.h"
#include "LayerDim.h"
#include "SurfaceFlinger.h"
@@ -90,6 +91,7 @@
mFreezeDisplayTime(0),
mDebugRegion(0),
mDebugBackground(0),
+ mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
@@ -108,13 +110,22 @@
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
+
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
+
property_get("debug.sf.showbackground", value, "0");
mDebugBackground = atoi(value);
+ property_get("debug.sf.ddms", value, "0");
+ mDebugDDMS = atoi(value);
+ if (mDebugDDMS) {
+ DdmConnection::start(getServiceName());
+ }
+
LOGI_IF(mDebugRegion, "showupdates enabled");
LOGI_IF(mDebugBackground, "showbackground enabled");
+ LOGI_IF(mDebugDDMS, "DDMS debugging enabled");
}
SurfaceFlinger::~SurfaceFlinger()
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6f93f5b..89df0de 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -371,6 +371,7 @@
// don't use a lock for these, we don't care
int mDebugRegion;
int mDebugBackground;
+ int mDebugDDMS;
int mDebugDisableHWC;
volatile nsecs_t mDebugInSwapBuffers;
nsecs_t mLastSwapBufferTime;