Merge change 24903 into eclair
* changes:
Fix some LayoutBridge javadoc.
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 3c2dc2b..f425f6b 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -1101,8 +1101,7 @@
}
CameraParameters p(params);
- mHardware->setParameters(p);
- return NO_ERROR;
+ return mHardware->setParameters(p);
}
// get preview/capture parameters - key/value pairs
diff --git a/cmds/keystore/Android.mk b/cmds/keystore/Android.mk
index 3daf44e..8804636 100644
--- a/cmds/keystore/Android.mk
+++ b/cmds/keystore/Android.mk
@@ -4,7 +4,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- netkeystore.c keymgmt.c
+ netkeystore.c netkeystore_main.c keymgmt.c
LOCAL_C_INCLUDES := \
$(call include-path-for, system-core)/cutils \
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c
index 69e0380..b5ace86 100644
--- a/cmds/keystore/keymgmt.c
+++ b/cmds/keystore/keymgmt.c
@@ -385,7 +385,10 @@
return -1;
}
while ((de = readdir(d))) {
- if (unlink(de->d_name) != 0) ret = -1;
+ char *dirname = de->d_name;
+ if (strcmp(".", dirname) == 0) continue;
+ if (strcmp("..", dirname) == 0) continue;
+ if (unlink(dirname) != 0) ret = -1;
}
closedir(d);
state = UNINITIALIZED;
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index 82a92c3..83c7871 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -14,8 +14,6 @@
** limitations under the License.
*/
-#define LOG_TAG "keystore"
-
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -247,7 +245,7 @@
reply->retcode = reset_keystore();
}
-static void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
+void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
{
uint32_t cmd_max = sizeof(cmds)/sizeof(struct cmdinfo);
@@ -309,7 +307,7 @@
return 0;
}
-static int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd)
+int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd)
{
uint32_t i, len = 0;
uint32_t cmd_max = sizeof(cmds)/sizeof(cmds[0]);
@@ -335,30 +333,30 @@
}
}
-static int shell_command(const int argc, const char **argv)
+int shell_command(const int argc, const char **argv)
{
int fd, i;
LPC_MARSHAL cmd;
- if (parse_cmd(argc, argv , &cmd)) {
+ if (parse_cmd(argc, argv, &cmd)) {
fprintf(stderr, "Incorrect command or command line is too long.\n");
- exit(1);
+ return -1;
}
fd = socket_local_client(SOCKET_PATH,
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_STREAM);
if (fd == -1) {
fprintf(stderr, "Keystore service is not up and running.\n");
- exit(1);
+ return -1;
}
if (write_marshal(fd, &cmd)) {
fprintf(stderr, "Incorrect command or command line is too long.\n");
- exit(1);
+ return -1;
}
if (read_marshal(fd, &cmd)) {
fprintf(stderr, "Failed to read the result.\n");
- exit(1);
+ return -1;
}
cmd.data[cmd.len] = 0;
fprintf(stdout, "%s\n", (cmd.retcode == 0) ? "Succeeded!" : "Failed!");
@@ -367,30 +365,26 @@
return 0;
}
-int main(const int argc, const char *argv[])
+int server_main(const int argc, const char *argv[])
{
struct sockaddr addr;
socklen_t alen;
int lsocket, s;
LPC_MARSHAL cmd, reply;
- if (argc > 1) {
- return shell_command(argc - 1, argv + 1);
- }
-
if (init_keystore(KEYSTORE_DIR)) {
LOGE("Can not initialize the keystore, the directory exist?\n");
- exit(1);
+ return -1;
}
lsocket = android_get_control_socket(SOCKET_PATH);
if (lsocket < 0) {
LOGE("Failed to get socket from environment: %s\n", strerror(errno));
- exit(1);
+ return -1;
}
if (listen(lsocket, 5)) {
LOGE("Listen on socket failed: %s\n", strerror(errno));
- exit(1);
+ return -1;
}
fcntl(lsocket, F_SETFD, FD_CLOEXEC);
memset(&reply, 0, sizeof(LPC_MARSHAL));
diff --git a/cmds/keystore/netkeystore.h b/cmds/keystore/netkeystore.h
index d80ddae..e2ffd8b 100644
--- a/cmds/keystore/netkeystore.h
+++ b/cmds/keystore/netkeystore.h
@@ -25,6 +25,10 @@
#include "common.h"
+// for testing
+int parse_cmd(int argc, const char **argv, LPC_MARSHAL *cmd);
+void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply);
+
static inline int readx(int s, void *_buf, int count)
{
char *buf = _buf;
diff --git a/cmds/keystore/netkeystore_main.c b/cmds/keystore/netkeystore_main.c
new file mode 100644
index 0000000..606e67a
--- /dev/null
+++ b/cmds/keystore/netkeystore_main.c
@@ -0,0 +1,29 @@
+/*
+** Copyright 2009, 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.
+*/
+
+#define LOG_TAG "keystore"
+
+int shell_command(const int argc, const char **argv);
+int server_main(const int argc, const char *argv[]);
+
+int main(const int argc, const char *argv[])
+{
+ if (argc > 1) {
+ return shell_command(argc - 1, argv + 1);
+ } else {
+ return server_main(argc, argv);
+ }
+}
diff --git a/cmds/keystore/tests/Android.mk b/cmds/keystore/tests/Android.mk
index 33541cc..e0a776a 100644
--- a/cmds/keystore/tests/Android.mk
+++ b/cmds/keystore/tests/Android.mk
@@ -16,7 +16,7 @@
ifdef KEYSTORE_TESTS
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c
+LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c ../netkeystore.c
LOCAL_SHARED_LIBRARIES := libcutils libssl
LOCAL_MODULE:= netkeystore_test
LOCAL_MODULE_TAGS := optional
diff --git a/cmds/keystore/tests/netkeystore_test.c b/cmds/keystore/tests/netkeystore_test.c
index 00390e0..ce79503 100644
--- a/cmds/keystore/tests/netkeystore_test.c
+++ b/cmds/keystore/tests/netkeystore_test.c
@@ -29,9 +29,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <cutils/log.h>
#include "common.h"
#include "keymgmt.h"
+#include "netkeystore.h"
+
+#define LOG_TAG "keystore_test"
typedef int FUNC_PTR();
typedef struct {
@@ -61,7 +65,9 @@
void teardown()
{
- reset_keystore();
+ if (reset_keystore() != 0) {
+ fprintf(stderr, "Can not reset the test directory %s\n", TEST_DIR);
+ }
rmdir(TEST_DIR);
}
@@ -74,7 +80,7 @@
FUNC_BODY(reset_keystore)
{
- chdir("/procx");
+ int ret = chdir("/proc");
if (reset_keystore() == 0) return -1;
chdir(TEST_DIR);
return EXIT_SUCCESS;
@@ -87,7 +93,8 @@
if (get_state() != UNLOCKED) return -1;
lock();
if (get_state() != LOCKED) return -1;
- reset_keystore();
+
+ if (reset_keystore() != 0) return -1;
if (get_state() != UNINITIALIZED) return -1;
return EXIT_SUCCESS;
}
@@ -218,6 +225,37 @@
return EXIT_SUCCESS;
}
+static int execute_cmd(int argc, const char *argv[], LPC_MARSHAL *cmd,
+ LPC_MARSHAL *reply)
+{
+ memset(cmd, 0, sizeof(LPC_MARSHAL));
+ memset(reply, 0, sizeof(LPC_MARSHAL));
+ if (parse_cmd(argc, argv, cmd)) return -1;
+ execute(cmd, reply);
+ return (reply->retcode ? -1 : 0);
+}
+
+FUNC_BODY(client_passwd)
+{
+ LPC_MARSHAL cmd, reply;
+ const char *set_passwd_cmds[2] = {"passwd", TEST_PASSWD};
+ const char *change_passwd_cmds[3] = {"passwd", TEST_PASSWD, TEST_NPASSWD};
+
+ if (execute_cmd(2, set_passwd_cmds, &cmd, &reply)) return -1;
+
+ lock();
+ if (unlock("55555555") == 0) return -1;
+ if (unlock(TEST_PASSWD) != 0) return -1;
+
+ if (execute_cmd(3, change_passwd_cmds, &cmd, &reply)) return -1;
+
+ lock();
+ if (unlock(TEST_PASSWD) == 0) return -1;
+ if (unlock(TEST_NPASSWD) != 0) return -1;
+
+ return EXIT_SUCCESS;
+}
+
TESTFUNC all_tests[] = {
FUNC_NAME(init_keystore),
FUNC_NAME(reset_keystore),
@@ -229,11 +267,13 @@
FUNC_NAME(get_key),
FUNC_NAME(remove_key),
FUNC_NAME(list_keys),
+ FUNC_NAME(client_passwd),
};
int main(int argc, char **argv) {
int i, ret;
for (i = 0 ; i < (int)(sizeof(all_tests)/sizeof(TESTFUNC)) ; ++i) {
+ LOGD("run %s...\n", all_tests[i].name);
setup();
if ((ret = all_tests[i].func()) != EXIT_SUCCESS) {
fprintf(stderr, "ERROR in function %s\n", all_tests[i].name);
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
index 2bd5344..6181f55 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/ui/SharedBufferStack.h
@@ -85,6 +85,7 @@
public:
SharedBufferStack();
+ void init(int32_t identity);
status_t setDirtyRegion(int buffer, const Region& reg);
Region getDirtyRegion(int buffer) const;
@@ -93,12 +94,12 @@
volatile int32_t available; // number of dequeue-able buffers
volatile int32_t queued; // number of buffers waiting for post
volatile int32_t inUse; // buffer currently in use by SF
+ volatile status_t status; // surface's status code
// not part of the conditions
volatile int32_t reallocMask;
int32_t identity; // surface's identity (const)
- status_t status; // surface's status code
int32_t reserved32[13];
FlatRegion dirtyRegion[NUM_BUFFER_MAX]; // 12*4=48 bytes
};
@@ -114,7 +115,6 @@
status_t validate(size_t token) const;
uint32_t getIdentity(size_t token) const;
- status_t setIdentity(size_t token, uint32_t identity);
private:
friend class SharedBufferBase;
@@ -168,10 +168,11 @@
template <typename T>
status_t SharedBufferBase::waitForCondition(T condition)
{
+ const SharedBufferStack& stack( *mSharedStack );
SharedClient& client( *mSharedClient );
const nsecs_t TIMEOUT = s2ns(1);
Mutex::Autolock _l(client.lock);
- while (!condition()) {
+ while ((condition()==false) && (stack.status == NO_ERROR)) {
status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
// handle errors and timeouts
@@ -195,7 +196,7 @@
}
}
}
- return NO_ERROR;
+ return stack.status;
}
@@ -261,13 +262,15 @@
class SharedBufferServer : public SharedBufferBase
{
public:
- SharedBufferServer(SharedClient* sharedClient, int surface, int num);
+ SharedBufferServer(SharedClient* sharedClient, int surface, int num,
+ int32_t identity);
ssize_t retireAndLock();
status_t unlock(int buffer);
+ void setStatus(status_t status);
status_t reallocate();
status_t assertReallocate(int buffer);
-
+
Region getDirtyRegion(int buffer) const;
private:
@@ -283,6 +286,12 @@
inline ssize_t operator()();
};
+ struct StatusUpdate : public UpdateBase {
+ const status_t status;
+ inline StatusUpdate(SharedBufferBase* sbb, status_t status);
+ inline ssize_t operator()();
+ };
+
struct ReallocateCondition : public ConditionBase {
int buf;
inline ReallocateCondition(SharedBufferBase* sbb, int buf);
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0fc533f..f5304f7 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -90,6 +90,11 @@
ANDROID_TGROUP_MAX = ANDROID_TGROUP_FG_BOOST,
};
+typedef enum {
+ SP_BACKGROUND = 0,
+ SP_FOREGROUND = 1,
+} SchedPolicy;
+
// Create and run a new thread.
extern int androidCreateThread(android_thread_func_t, void *);
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index e2b6b51..790a655 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -2014,6 +2014,7 @@
: RefBase(),
mThread(thread),
mClient(client),
+ mCblk(0),
mFrameCount(0),
mState(IDLE),
mClientTid(-1),
@@ -2162,21 +2163,23 @@
: TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer),
mMute(false), mSharedBuffer(sharedBuffer), mName(-1)
{
- sp<ThreadBase> baseThread = thread.promote();
- if (baseThread != 0) {
- PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();
- mName = playbackThread->getTrackName_l();
+ if (mCblk != NULL) {
+ sp<ThreadBase> baseThread = thread.promote();
+ if (baseThread != 0) {
+ PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();
+ mName = playbackThread->getTrackName_l();
+ }
+ LOGV("Track constructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+ if (mName < 0) {
+ LOGE("no more track names available");
+ }
+ mVolume[0] = 1.0f;
+ mVolume[1] = 1.0f;
+ mStreamType = streamType;
+ // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
+ // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
+ mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);
}
- LOGV("Track constructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
- if (mName < 0) {
- LOGE("no more track names available");
- }
- mVolume[0] = 1.0f;
- mVolume[1] = 1.0f;
- mStreamType = streamType;
- // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
- // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
- mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);
}
AudioFlinger::PlaybackThread::Track::~Track()
@@ -2390,14 +2393,16 @@
channelCount, frameCount, flags, 0),
mOverflow(false)
{
- LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
- if (format == AudioSystem::PCM_16_BIT) {
- mCblk->frameSize = channelCount * sizeof(int16_t);
- } else if (format == AudioSystem::PCM_8_BIT) {
- mCblk->frameSize = channelCount * sizeof(int8_t);
- } else {
- mCblk->frameSize = sizeof(int8_t);
- }
+ if (mCblk != NULL) {
+ LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
+ if (format == AudioSystem::PCM_16_BIT) {
+ mCblk->frameSize = channelCount * sizeof(int16_t);
+ } else if (format == AudioSystem::PCM_8_BIT) {
+ mCblk->frameSize = channelCount * sizeof(int8_t);
+ } else {
+ mCblk->frameSize = sizeof(int8_t);
+ }
+ }
}
AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index ecb6b32..6275910 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -49,13 +49,12 @@
Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& c, int32_t i)
- : LayerBaseClient(flinger, display, c, i), lcblk(NULL),
+ : LayerBaseClient(flinger, display, c, i),
mSecure(false),
mNeedsBlending(true)
{
// no OpenGL operation is possible here, since we might not be
// in the OpenGL thread.
- lcblk = new SharedBufferServer(c->ctrlblk, i, NUM_BUFFERS);
mFrontBufferIndex = lcblk->getFrontBuffer();
}
@@ -63,8 +62,14 @@
{
destroy();
// the actual buffers will be destroyed here
- delete lcblk;
+}
+// called with SurfaceFlinger::mStateLock as soon as the layer is entered
+// in the purgatory list
+void Layer::onRemoved()
+{
+ // wake up the condition
+ lcblk->setStatus(NO_INIT);
}
void Layer::destroy()
@@ -79,7 +84,9 @@
eglDestroyImageKHR(dpy, mTextures[i].image);
mTextures[i].image = EGL_NO_IMAGE_KHR;
}
+ Mutex::Autolock _l(mLock);
mBuffers[i].clear();
+ mWidth = mHeight = 0;
}
mSurface.clear();
}
@@ -213,6 +220,16 @@
sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
{
+ sp<Buffer> buffer;
+
+ // this ensures our client doesn't go away while we're accessing
+ // the shared area.
+ sp<Client> ourClient(client.promote());
+ if (ourClient == 0) {
+ // oops, the client is already gone
+ return buffer;
+ }
+
/*
* This is called from the client's Surface::dequeue(). This can happen
* at any time, especially while we're in the middle of using the
@@ -225,12 +242,21 @@
*/
status_t err = lcblk->assertReallocate(index);
LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
+ if (err != NO_ERROR) {
+ // the surface may have died
+ return buffer;
+ }
- Mutex::Autolock _l(mLock);
- uint32_t w = mWidth;
- uint32_t h = mHeight;
-
- sp<Buffer>& buffer(mBuffers[index]);
+ uint32_t w, h;
+ { // scope for the lock
+ Mutex::Autolock _l(mLock);
+ w = mWidth;
+ h = mHeight;
+ buffer = mBuffers[index];
+ mBuffers[index].clear();
+ }
+
+
if (buffer->getStrongCount() == 1) {
err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
} else {
@@ -253,8 +279,16 @@
}
if (err == NO_ERROR && buffer->handle != 0) {
- // texture is now dirty...
- mTextures[index].dirty = true;
+ Mutex::Autolock _l(mLock);
+ if (mWidth && mHeight) {
+ // and we have new buffer
+ mBuffers[index] = buffer;
+ // texture is now dirty...
+ mTextures[index].dirty = true;
+ } else {
+ // oops we got killed while we were allocating the buffer
+ buffer.clear();
+ }
}
return buffer;
}
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 3b4489e..2e8173d 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -51,10 +51,6 @@
static const char* const typeID;
virtual char const* getTypeID() const { return typeID; }
virtual uint32_t getTypeInfo() const { return typeInfo; }
-
-
- SharedBufferServer* lcblk;
-
Layer(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i);
@@ -88,6 +84,8 @@
return mBuffers[mFrontBufferIndex];
}
+ virtual void onRemoved();
+
void reloadTexture(const Region& dirty);
sp<SurfaceBuffer> requestBuffer(int index, int usage);
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 62e41b0..1f22488 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -642,9 +642,12 @@
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i)
- : LayerBase(flinger, display), client(client),
+ : LayerBase(flinger, display), lcblk(NULL), client(client),
mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
{
+ lcblk = new SharedBufferServer(
+ client->ctrlblk, i, NUM_BUFFERS,
+ mIdentity);
}
void LayerBaseClient::onFirstRef()
@@ -652,8 +655,6 @@
sp<Client> client(this->client.promote());
if (client != 0) {
client->bindLayer(this, mIndex);
- // Initialize this layer's identity
- client->ctrlblk->setIdentity(mIndex, mIdentity);
}
}
@@ -663,6 +664,7 @@
if (client != 0) {
client->free(mIndex);
}
+ delete lcblk;
}
int32_t LayerBaseClient::serverIndex() const
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 78bb4bf..3a52240 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -292,13 +292,16 @@
virtual char const* getTypeID() const { return typeID; }
virtual uint32_t getTypeInfo() const { return typeInfo; }
+ // lcblk is (almost) only accessed from the main SF thread, in the places
+ // where it's not, a reference to Client must be held
+ SharedBufferServer* lcblk;
+
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i);
virtual ~LayerBaseClient();
virtual void onFirstRef();
- wp<Client> client;
-// SharedBufferServer* lcblk;
+ const wp<Client> client;
inline uint32_t getIdentity() const { return mIdentity; }
inline int32_t clientIndex() const { return mIndex; }
@@ -308,6 +311,7 @@
sp<Surface> getSurface();
virtual sp<Surface> createSurface() const;
+ virtual void onRemoved() { }
class Surface : public BnSurface
{
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index b368db6..8685f99 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -654,6 +654,7 @@
// some layers might have been removed, so
// we need to update the regions they're exposing.
if (mLayersRemoved) {
+ mLayersRemoved = false;
mVisibleRegionsDirty = true;
const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
const size_t count = previousLayers.size();
@@ -1093,9 +1094,6 @@
void SurfaceFlinger::free_resources_l()
{
- // Destroy layers that were removed
- mLayersRemoved = false;
-
// free resources associated with disconnected clients
Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
const size_t count = disconnectedClients.size();
@@ -1321,11 +1319,15 @@
* to wait for all client's references to go away first).
*/
+ status_t err = NAME_NOT_FOUND;
Mutex::Autolock _l(mStateLock);
sp<LayerBaseClient> layer = getLayerUser_l(index);
- status_t err = purgatorizeLayer_l(layer);
- if (err == NO_ERROR) {
- setTransactionFlags(eTransactionNeeded);
+ if (layer != 0) {
+ err = purgatorizeLayer_l(layer);
+ if (err == NO_ERROR) {
+ layer->onRemoved();
+ setTransactionFlags(eTransactionNeeded);
+ }
}
return err;
}
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
index 5995af5..436d793 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/ui/SharedBufferStack.cpp
@@ -53,21 +53,20 @@
return uint32_t(surfaces[token].identity);
}
-status_t SharedClient::setIdentity(size_t token, uint32_t identity) {
- if (token >= NUM_LAYERS_MAX)
- return BAD_INDEX;
- surfaces[token].identity = identity;
- return NO_ERROR;
-}
-
// ----------------------------------------------------------------------------
SharedBufferStack::SharedBufferStack()
- : inUse(-1), identity(-1), status(NO_ERROR)
{
}
+void SharedBufferStack::init(int32_t i)
+{
+ inUse = -1;
+ status = NO_ERROR;
+ identity = i;
+}
+
status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
{
if (uint32_t(buffer) >= NUM_BUFFER_MAX)
@@ -231,16 +230,46 @@
return head;
}
+SharedBufferServer::StatusUpdate::StatusUpdate(
+ SharedBufferBase* sbb, status_t status)
+ : UpdateBase(sbb), status(status) {
+}
+
+ssize_t SharedBufferServer::StatusUpdate::operator()() {
+ android_atomic_write(status, &stack.status);
+ return NO_ERROR;
+}
+
// ============================================================================
SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
int surface, int num)
: SharedBufferBase(sharedClient, surface, num), tail(0)
{
+ SharedBufferStack& stack( *mSharedStack );
+ int32_t avail;
+ int32_t head;
+ // we need to make sure we read available and head coherently,
+ // w.r.t RetireUpdate.
+ do {
+ avail = stack.available;
+ head = stack.head;
+ } while (stack.available != avail);
+ tail = head - avail + 1;
+ if (tail < 0) {
+ tail += num;
+ }
}
ssize_t SharedBufferClient::dequeue()
{
+ SharedBufferStack& stack( *mSharedStack );
+
+ if (stack.head == tail && stack.available == 2) {
+ LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
+ tail, stack.head, stack.available, stack.queued);
+ }
+
//LOGD("[%d] about to dequeue a buffer",
// mSharedStack->identity);
DequeueCondition condition(this);
@@ -248,8 +277,6 @@
if (err != NO_ERROR)
return ssize_t(err);
-
- SharedBufferStack& stack( *mSharedStack );
// NOTE: 'stack.available' is part of the conditions, however
// decrementing it, never changes any conditions, so we don't need
// to do this as part of an update.
@@ -261,6 +288,7 @@
tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
dequeued, tail, dump("").string());
+
return dequeued;
}
@@ -302,9 +330,10 @@
// ----------------------------------------------------------------------------
SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
- int surface, int num)
+ int surface, int num, int32_t identity)
: SharedBufferBase(sharedClient, surface, num)
{
+ mSharedStack->init(identity);
mSharedStack->head = num-1;
mSharedStack->available = num;
mSharedStack->queued = 0;
@@ -316,7 +345,7 @@
{
RetireUpdate update(this, mNumBuffers);
ssize_t buf = updateCondition( update );
- LOGD_IF(DEBUG_ATOMICS, "retire=%d, %s", int(buf), dump("").string());
+ LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s", int(buf), dump("").string());
return buf;
}
@@ -327,6 +356,12 @@
return err;
}
+void SharedBufferServer::setStatus(status_t status)
+{
+ StatusUpdate update(this, status);
+ updateCondition( update );
+}
+
status_t SharedBufferServer::reallocate()
{
SharedBufferStack& stack( *mSharedStack );
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 4d3c2f4..90e6d29 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -118,10 +118,10 @@
/*
* If the active textures are EGLImage, they need to be locked before
- * they can be used.
- *
+ * they can be used.
+ *
* FIXME: code below is far from being optimal
- *
+ *
*/
void ogles_lock_textures(ogles_context_t* c)
@@ -409,6 +409,49 @@
return 0;
}
+static size_t dataSizePalette4(int numLevels, int width, int height, int format)
+{
+ int indexBits = 8;
+ int entrySize = 0;
+ switch (format) {
+ case GL_PALETTE4_RGB8_OES:
+ indexBits = 4;
+ /* FALLTHROUGH */
+ case GL_PALETTE8_RGB8_OES:
+ entrySize = 3;
+ break;
+
+ case GL_PALETTE4_RGBA8_OES:
+ indexBits = 4;
+ /* FALLTHROUGH */
+ case GL_PALETTE8_RGBA8_OES:
+ entrySize = 4;
+ break;
+
+ case GL_PALETTE4_R5_G6_B5_OES:
+ case GL_PALETTE4_RGBA4_OES:
+ case GL_PALETTE4_RGB5_A1_OES:
+ indexBits = 4;
+ /* FALLTHROUGH */
+ case GL_PALETTE8_R5_G6_B5_OES:
+ case GL_PALETTE8_RGBA4_OES:
+ case GL_PALETTE8_RGB5_A1_OES:
+ entrySize = 2;
+ break;
+ }
+
+ size_t size = (1 << indexBits) * entrySize; // palette size
+
+ for (int i=0 ; i< numLevels ; i++) {
+ int w = (width >> i) ? : 1;
+ int h = (height >> i) ? : 1;
+ int levelSize = h * ((w * indexBits) / 8) ? : 1;
+ size += levelSize;
+ }
+
+ return size;
+}
+
static void decodePalette4(const GLvoid *data, int level, int width, int height,
void *surface, int stride, int format)
@@ -443,6 +486,7 @@
}
const int paletteSize = (1 << indexBits) * entrySize;
+
uint8_t const* pixels = (uint8_t *)data + paletteSize;
for (int i=0 ; i<level ; i++) {
int w = (width >> i) ? : 1;
@@ -652,7 +696,7 @@
ogles_context_t* c)
{
ogles_lock_textures(c);
-
+
const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
y = gglIntToFixed(cbSurface.height) - (y + h);
w >>= FIXED_BITS;
@@ -799,7 +843,7 @@
c->rasterizer.procs.disable(c, GGL_AA);
c->rasterizer.procs.shadeModel(c, GL_FLAT);
c->rasterizer.procs.recti(c, x, y, x+w, y+h);
-
+
ogles_unlock_textures(c);
return;
@@ -1091,6 +1135,12 @@
GGLSurface* surface;
// all mipmap levels are specified at once.
const int numLevels = level<0 ? -level : 1;
+
+ if (dataSizePalette4(numLevels, width, height, format) > imageSize) {
+ ogles_error(c, GL_INVALID_VALUE);
+ return;
+ }
+
for (int i=0 ; i<numLevels ; i++) {
int lod_w = (width >> i) ? : 1;
int lod_h = (height >> i) ? : 1;