Merge change 25528 into eclair
* changes:
Another stagefright test-case and ignore end-of-stream notifications while we're flushing.
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index 83c7871..87fdc80 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -116,10 +116,13 @@
static int is_alnum_string(char *s)
{
+ char *s0 = s;
while (*s != 0) {
- if (!isalnum(*s++)) return 0;
+ if (!isalnum(*s++)) {
+ LOGE("The string '%s' is not an alphanumeric string\n", s0);
+ return 0;
+ }
}
- LOGE("The string %s is not an alphanumeric string\n", s);
return 1;
}
@@ -159,7 +162,9 @@
// no argument
static void do_get_state(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
{
- reply->retcode = get_state();
+ int s = get_state();
+ if (DBG) LOGD("keystore state = %d\n", s);
+ reply->retcode = s;
}
// args of listkeys():
@@ -413,12 +418,10 @@
// read the command, execute and send the result back.
if(read_marshal(s, &cmd)) goto err;
- if (DBG) LOGD("new connection\n");
execute(&cmd, &reply);
write_marshal(s, &reply);
err:
memset(&reply, 0, sizeof(LPC_MARSHAL));
- if (DBG) LOGD("closing connection\n");
close(s);
}
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
index 8b0f154..c02b2e7 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/ui/SharedBufferStack.h
@@ -69,12 +69,6 @@
// ----------------------------------------------------------------------------
-struct FlatRegion { // 12 bytes
- static const unsigned int NUM_RECT_MAX = 1;
- uint32_t count;
- uint16_t rects[4*NUM_RECT_MAX];
-};
-
// should be 128 bytes (32 longs)
class SharedBufferStack
{
@@ -84,6 +78,18 @@
friend class SharedBufferServer;
public:
+ struct FlatRegion { // 12 bytes
+ static const unsigned int NUM_RECT_MAX = 1;
+ uint32_t count;
+ uint16_t rects[4*NUM_RECT_MAX];
+ };
+
+ struct Statistics { // 4 longs
+ typedef int32_t usecs_t;
+ usecs_t totalTime;
+ usecs_t reserved[3];
+ };
+
SharedBufferStack();
void init(int32_t identity);
status_t setDirtyRegion(int buffer, const Region& reg);
@@ -100,7 +106,8 @@
volatile int32_t reallocMask;
int32_t identity; // surface's identity (const)
- int32_t reserved32[13];
+ int32_t reserved32[9];
+ Statistics stats;
FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes
};
@@ -223,7 +230,7 @@
status_t queue(int buf);
bool needNewBuffer(int buffer) const;
status_t setDirtyRegion(int buffer, const Region& reg);
-
+
private:
friend struct Condition;
friend struct DequeueCondition;
@@ -257,6 +264,8 @@
};
int32_t tail;
+ // statistics...
+ nsecs_t mDequeueTime[NUM_BUFFER_MAX];
};
// ----------------------------------------------------------------------------
@@ -275,6 +284,9 @@
Region getDirtyRegion(int buffer) const;
+ SharedBufferStack::Statistics getStats() const;
+
+
private:
struct UnlockUpdate : public UpdateBase {
const int lockedBuffer;
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp
index 5dc0ba0..1ffbd5b 100644
--- a/libs/surfaceflinger/BlurFilter.cpp
+++ b/libs/surfaceflinger/BlurFilter.cpp
@@ -111,6 +111,50 @@
}
};
+template <int FACTOR = 0>
+struct BlurColor888X
+{
+ typedef uint32_t type;
+ int r, g, b;
+ inline BlurColor888X() { }
+ inline BlurColor888X(uint32_t v) {
+ v = BLUR_RGBA_TO_HOST(v);
+ r = v & 0xFF;
+ g = (v >> 8) & 0xFF;
+ b = (v >> 16) & 0xFF;
+ }
+ inline void clear() { r=g=b=0; }
+ inline uint32_t to(int shift, int last, int dither) const {
+ int R = r;
+ int G = g;
+ int B = b;
+ if (UNLIKELY(last)) {
+ if (FACTOR>0) {
+ int L = (R+G+G+B)>>2;
+ R += ((L - R) * FACTOR) >> 8;
+ G += ((L - G) * FACTOR) >> 8;
+ B += ((L - B) * FACTOR) >> 8;
+ }
+ }
+ R >>= shift;
+ G >>= shift;
+ B >>= shift;
+ return BLUR_HOST_TO_RGBA((0xFF<<24) | (B<<16) | (G<<8) | R);
+ }
+ inline BlurColor888X& operator += (const BlurColor888X& rhs) {
+ r += rhs.r;
+ g += rhs.g;
+ b += rhs.b;
+ return *this;
+ }
+ inline BlurColor888X& operator -= (const BlurColor888X& rhs) {
+ r -= rhs.r;
+ g -= rhs.g;
+ b -= rhs.b;
+ return *this;
+ }
+};
+
struct BlurGray565
{
typedef uint16_t type;
@@ -316,7 +360,13 @@
int kernelSizeUser,
int repeat)
{
- return blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+ status_t err = BAD_VALUE;
+ if (image->format == GGL_PIXEL_FORMAT_RGB_565) {
+ err = blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+ } else if (image->format == GGL_PIXEL_FORMAT_RGBX_8888) {
+ err = blurFilter< BlurColor888X<0x80> >(image, image, kernelSizeUser, repeat);
+ }
+ return err;
}
} // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index d893f0a..cc913cb 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -174,6 +174,13 @@
surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+ if (mFlags & UPDATE_ON_DEMAND) {
+ // if we have update on demand, we definitely don't need to
+ // preserve the backbuffer, which is usually costly.
+ eglSurfaceAttrib(display, surface,
+ EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+ }
+
if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
if (dummy == EGL_BUFFER_PRESERVED) {
mFlags |= BUFFER_PRESERVED;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 1e7f1e6..7387c85 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -303,7 +303,6 @@
// Index of the back buffer
const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
-
if (backbufferChanged) {
// the size changed, we need to ask our client to request a new buffer
LOGD_IF(DEBUG_RESIZE,
@@ -318,17 +317,6 @@
// buffer, it'll get the new size.
setDrawingSize(temp.w, temp.h);
- // all buffers need reallocation
- lcblk->reallocate();
-
- // recompute the visible region
- // FIXME: ideally we would do that only when we have received
- // a buffer of the right size
- flags |= Layer::eVisibleRegion;
- this->contentDirty = true;
-
-#if 0
- // FIXME: handle freeze lock
// we're being resized and there is a freeze display request,
// acquire a freeze lock, so that the screen stays put
// until we've redrawn at the new size; this is to avoid
@@ -340,7 +328,12 @@
mFreezeLock = mFlinger->getFreezeLock();
}
}
-#endif
+
+ // recompute the visible region
+ flags |= Layer::eVisibleRegion;
+ this->contentDirty = true;
+ // all buffers need reallocation
+ lcblk->reallocate();
}
if (temp.sequence != front.sequence) {
@@ -382,6 +375,13 @@
const Region dirty(lcblk->getDirtyRegion(buf));
mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
+
+ const Layer::State& front(drawingState());
+ if (newFrontBuffer->getWidth() == front.w &&
+ newFrontBuffer->getHeight() ==front.h) {
+ mFreezeLock.clear();
+ }
+
// FIXME: signal an event if we have more buffers waiting
// mFlinger->signalEvent();
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index e14f35b..0ef663f 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -40,9 +40,9 @@
LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i)
- : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
- mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
- mWidthScale(1.0f), mHeightScale(1.0f)
+: LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
+mWidthScale(1.0f), mHeightScale(1.0f)
{
}
@@ -136,6 +136,13 @@
// create the texture name the first time
// can't do that in the ctor, because it runs in another thread.
glGenTextures(1, &mTextureName);
+ glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat);
+ glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType);
+ if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) {
+ mReadFormat = GL_RGBA;
+ mReadType = GL_UNSIGNED_BYTE;
+ mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888;
+ }
}
Region::const_iterator it = clip.begin();
@@ -143,33 +150,39 @@
if (it != end) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, mTextureName);
-
+
if (mRefreshCache) {
mRefreshCache = false;
mAutoRefreshPending = false;
-
- // allocate enough memory for 4-bytes (2 pixels) aligned data
- const int32_t s = (w + 1) & ~1;
- uint16_t* const pixels = (uint16_t*)malloc(s*h*2);
+
+ int32_t pixelSize = 4;
+ int32_t s = w;
+ if (mReadType == GL_UNSIGNED_SHORT_5_6_5) {
+ // allocate enough memory for 4-bytes (2 pixels) aligned data
+ s = (w + 1) & ~1;
+ pixelSize = 2;
+ }
+
+ uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize);
// This reads the frame-buffer, so a h/w GL would have to
// finish() its rendering first. we don't want to do that
// too often. Read data is 4-bytes aligned.
- glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
-
+ glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels);
+
// blur that texture.
GGLSurface bl;
bl.version = sizeof(GGLSurface);
bl.width = w;
bl.height = h;
bl.stride = s;
- bl.format = GGL_PIXEL_FORMAT_RGB_565;
+ bl.format = mBlurFormat;
bl.data = (GGLubyte*)pixels;
blurFilter(&bl, 8, 2);
if (mFlags & (DisplayHardware::NPOT_EXTENSION)) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+ glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
+ mReadFormat, mReadType, pixels);
mWidthScale = 1.0f / w;
mHeightScale =-1.0f / h;
mYOffset = 0;
@@ -178,10 +191,10 @@
GLuint th = 1 << (31 - clz(h));
if (tw < w) tw <<= 1;
if (th < h) th <<= 1;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0,
+ mReadFormat, mReadType, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
- GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+ mReadFormat, mReadType, pixels);
mWidthScale = 1.0f / tw;
mHeightScale =-1.0f / th;
mYOffset = th-h;
@@ -189,7 +202,7 @@
free((void*)pixels);
}
-
+
const State& s = drawingState();
if (UNLIKELY(s.alpha < 0xFF)) {
const GGLfixed alpha = (s.alpha << 16)/255;
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
index bf36ae4..2e9d7c6 100644
--- a/libs/surfaceflinger/LayerBlur.h
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -59,6 +59,9 @@
mutable GLfloat mWidthScale;
mutable GLfloat mHeightScale;
mutable GLfloat mYOffset;
+ mutable GLint mReadFormat;
+ mutable GLint mReadType;
+ mutable uint32_t mBlurFormat;
};
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 38a897d..667571b 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -595,6 +595,7 @@
*overlayRef = new OverlayRef(mOverlayHandle, channel,
mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
+ mLayer.mFlinger->signalEvent();
}
LayerBuffer::OverlaySource::~OverlaySource()
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index a352431..31b5128 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1521,6 +1521,7 @@
/*** Layer ***/
sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
if (l != 0) {
+ SharedBufferStack::Statistics stats = l->lcblk->getStats();
result.append( l->lcblk->dump(" ") );
sp<const Buffer> buf0(l->getBuffer(0));
sp<const Buffer> buf1(l->getBuffer(1));
@@ -1539,10 +1540,10 @@
snprintf(buffer, SIZE,
" "
"format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
- " freezeLock=%p\n",
+ " freezeLock=%p, dq-q-time=%u us\n",
l->pixelFormat(),
w0, h0, s0, w1, h1, s1,
- l->getFreezeLock().get());
+ l->getFreezeLock().get(), stats.totalTime);
result.append(buffer);
buffer[0] = 0;
}
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
index 7789a3f..9ad4349 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/ui/SharedBufferStack.cpp
@@ -276,6 +276,8 @@
LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
tail, stack.head, stack.available, stack.queued);
}
+
+ const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
//LOGD("[%d] about to dequeue a buffer",
// mSharedStack->identity);
@@ -296,6 +298,8 @@
LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
dequeued, tail, dump("").string());
+ mDequeueTime[dequeued] = dequeueTime;
+
return dequeued;
}
@@ -312,7 +316,7 @@
status_t SharedBufferClient::lock(int buf)
{
LockCondition condition(this, buf);
- status_t err = waitForCondition(condition);
+ status_t err = waitForCondition(condition);
return err;
}
@@ -321,6 +325,9 @@
QueueUpdate update(this);
status_t err = updateCondition( update );
LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
+ SharedBufferStack& stack( *mSharedStack );
+ const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
+ stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
return err;
}
@@ -393,5 +400,12 @@
return stack.getDirtyRegion(buffer);
}
+SharedBufferStack::Statistics SharedBufferServer::getStats() const
+{
+ SharedBufferStack& stack( *mSharedStack );
+ return stack.stats;
+}
+
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index f969a46..d4887ba 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -34,14 +34,16 @@
static void printGLString(const char *name, GLenum s)
{
fprintf(stderr, "printGLString %s, %d\n", name, s);
+#if 0 // causes hangs
const char *v = (const char *)glGetString(s);
int error = glGetError();
fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
(unsigned int)v);
- if ((v < (const char*) 0) || (v > (const char*) 0x1000))
+ if ((v < (const char*) 0) || (v > (const char*) 0x10000))
fprintf(stderr, "GL %s = %s\n", name, v);
else
- fprintf(stderr, "GL %s = (null)\n", name);
+ fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+#endif
}
static const char* eglErrorToString[] = {
@@ -61,7 +63,11 @@
"EGL_BAD_SURFACE"
};
-static void checkEglError(const char* op) {
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+ if (returnVal != EGL_TRUE) {
+ fprintf(stderr, "%s() returned %d\n", op, returnVal);
+ }
+
for(EGLint error = eglGetError();
error != EGL_SUCCESS;
error = eglGetError()) {
@@ -69,25 +75,30 @@
if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
errorString = eglErrorToString[error - EGL_SUCCESS];
}
- fprintf(stderr, "%s() returned eglError %s (0x%x)\n", op,
+ fprintf(stderr, "after %s() eglError %s (0x%x)\n", op,
errorString, error);
}
}
int main(int argc, char** argv)
{
+ EGLBoolean returnValue;
+ EGLConfig configs[2];
+ EGLint config_count;
+
+ EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
EGLint s_configAttribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5,
- EGL_NONE
+ EGL_BUFFER_SIZE, EGL_DONT_CARE,
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_DEPTH_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
};
- EGLint numConfigs = -1;
EGLint majorVersion;
EGLint minorVersion;
- EGLConfig config;
EGLContext context;
EGLSurface surface;
EGLint w, h;
@@ -100,20 +111,50 @@
checkEglError("<init>");
dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
checkEglError("eglGetDisplay");
- eglInitialize(dpy, &majorVersion, &minorVersion);
- checkEglError("eglInitialize");
+ if (dpy == EGL_NO_DISPLAY) {
+ printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+ return 0;
+ }
+ returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+ checkEglError("eglInitialize", returnValue);
fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+
+ returnValue = eglGetConfigs (dpy, configs, 2, &config_count);
+ checkEglError("eglGetConfigs", returnValue);
+ fprintf(stderr, "Config count: %d\n", config_count);
+ for(int i = 0; i < config_count; i++) {
+ fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
+ }
+#if 0
+ EGLConfig config;
EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
- fprintf(stderr, "Chosen config: 0x%08x\n", (unsigned long) config);
-
checkEglError("EGLUtils::selectConfigForNativeWindow");
- surface = eglCreateWindowSurface(dpy, config, window, NULL);
- checkEglError("eglCreateWindowSurface");
+#else
+ int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs, configs, 2, &config_count);
+ checkEglError("eglChooseConfig", chooseConfigResult);
+ if (chooseConfigResult != EGL_TRUE )
+ {
+ printf("eglChooseConfig failed\n");
+ return 0;
+ }
+#endif
+ surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+ checkEglError("eglCreateWindowSurface");
+ if (surface == EGL_NO_SURFACE)
+ {
+ printf("gelCreateWindowSurface failed.\n");
+ return 0;
+ }
EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
- context = eglCreateContext(dpy, config, NULL, gl2_0Attribs);
+ context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
checkEglError("eglCreateContext");
+ if (context == EGL_NO_CONTEXT)
+ {
+ printf("eglCreateContext failed\n");
+ return 0;
+ }
eglMakeCurrent(dpy, surface, surface, context);
checkEglError("eglMakeCurrent");
eglQuerySurface(dpy, surface, EGL_WIDTH, &w);