Merge change I98819b18 into eclair-mr2
* changes:
Allow resource and file URIs in ImageView.setImageURI()
diff --git a/calendar/Android.mk b/calendar/Android.mk
new file mode 100644
index 0000000..fd20dfa
--- /dev/null
+++ b/calendar/Android.mk
@@ -0,0 +1,18 @@
+# Copyright 2009 Google, Inc.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := calendar
+LOCAL_SRC_FILES := \
+ ../core/java/android/provider/Calendar.java \
+ ../core/java/android/pim/EventRecurrence.java \
+ ../core/java/android/pim/ICalendar.java \
+ ../core/java/android/pim/RecurrenceSet.java \
+ ../core/java/android/pim/ContactsAsyncHelper.java \
+ ../core/java/android/pim/DateException.java
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Include this library in the build server's output directory
+$(call dist-for-goals, droid, $(LOCAL_BUILT_MODULE):calendar.jar)
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index df59dcf..6419a5c 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -669,8 +669,14 @@
LOGD("startRecording (pid %d)", getCallingPid());
if (mMediaPlayerBeep.get() != NULL) {
- mMediaPlayerBeep->seekTo(0);
- mMediaPlayerBeep->start();
+ // do not play record jingle if stream volume is 0
+ // (typically because ringer mode is silent).
+ int index;
+ AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+ if (index != 0) {
+ mMediaPlayerBeep->seekTo(0);
+ mMediaPlayerBeep->start();
+ }
}
mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME);
@@ -888,8 +894,14 @@
{
// Play shutter sound.
if (mMediaPlayerClick.get() != NULL) {
- mMediaPlayerClick->seekTo(0);
- mMediaPlayerClick->start();
+ // do not play shutter sound if stream volume is 0
+ // (typically because ringer mode is silent).
+ int index;
+ AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
+ if (index != 0) {
+ mMediaPlayerClick->seekTo(0);
+ mMediaPlayerClick->start();
+ }
}
// Screen goes black after the buffer is unregistered.
diff --git a/camera/tests/CameraServiceTest/Android.mk b/camera/tests/CameraServiceTest/Android.mk
new file mode 100644
index 0000000..c2a02bb
--- /dev/null
+++ b/camera/tests/CameraServiceTest/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= CameraServiceTest.cpp
+
+LOCAL_MODULE:= CameraServiceTest
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES += \
+ frameworks/base/libs
+
+LOCAL_CFLAGS :=
+
+LOCAL_SHARED_LIBRARIES += \
+ libcutils \
+ libutils \
+ libui
+
+include $(BUILD_EXECUTABLE)
diff --git a/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
new file mode 100644
index 0000000..29320e0
--- /dev/null
+++ b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -0,0 +1,848 @@
+#define LOG_TAG "CameraServiceTest"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <ui/ISurface.h>
+#include <ui/Camera.h>
+#include <ui/CameraParameters.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/ICamera.h>
+#include <ui/ICameraClient.h>
+#include <ui/ICameraService.h>
+#include <ui/Overlay.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+using namespace android;
+
+//
+// Assertion and Logging utilities
+//
+#define INFO(...) \
+ do { \
+ printf(__VA_ARGS__); \
+ printf("\n"); \
+ LOGD(__VA_ARGS__); \
+ } while(0)
+
+void assert_fail(const char *file, int line, const char *func, const char *expr) {
+ INFO("assertion failed at file %s, line %d, function %s:",
+ file, line, func);
+ INFO("%s", expr);
+ exit(1);
+}
+
+void assert_eq_fail(const char *file, int line, const char *func,
+ const char *expr, int actual) {
+ INFO("assertion failed at file %s, line %d, function %s:",
+ file, line, func);
+ INFO("(expected) %s != (actual) %d", expr, actual);
+ exit(1);
+}
+
+#define ASSERT(e) \
+ do { \
+ if (!(e)) \
+ assert_fail(__FILE__, __LINE__, __func__, #e); \
+ } while(0)
+
+#define ASSERT_EQ(expected, actual) \
+ do { \
+ int _x = (actual); \
+ if (_x != (expected)) \
+ assert_eq_fail(__FILE__, __LINE__, __func__, #expected, _x); \
+ } while(0)
+
+//
+// Holder service for pass objects between processes.
+//
+class IHolder : public IInterface {
+protected:
+ enum {
+ HOLDER_PUT = IBinder::FIRST_CALL_TRANSACTION,
+ HOLDER_GET,
+ HOLDER_CLEAR
+ };
+public:
+ DECLARE_META_INTERFACE(Holder);
+
+ virtual void put(sp<IBinder> obj) = 0;
+ virtual sp<IBinder> get() = 0;
+ virtual void clear() = 0;
+};
+
+class BnHolder : public BnInterface<IHolder> {
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+class BpHolder : public BpInterface<IHolder> {
+public:
+ BpHolder(const sp<IBinder>& impl)
+ : BpInterface<IHolder>(impl) {
+ }
+
+ virtual void put(sp<IBinder> obj) {
+ Parcel data, reply;
+ data.writeStrongBinder(obj);
+ remote()->transact(HOLDER_PUT, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ virtual sp<IBinder> get() {
+ Parcel data, reply;
+ remote()->transact(HOLDER_GET, data, &reply);
+ return reply.readStrongBinder();
+ }
+
+ virtual void clear() {
+ Parcel data, reply;
+ remote()->transact(HOLDER_CLEAR, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(Holder, "CameraServiceTest.Holder");
+
+status_t BnHolder::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+ switch(code) {
+ case HOLDER_PUT: {
+ put(data.readStrongBinder());
+ return NO_ERROR;
+ } break;
+ case HOLDER_GET: {
+ reply->writeStrongBinder(get());
+ return NO_ERROR;
+ } break;
+ case HOLDER_CLEAR: {
+ clear();
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+class HolderService : public BnHolder {
+ virtual void put(sp<IBinder> obj) {
+ mObj = obj;
+ }
+ virtual sp<IBinder> get() {
+ return mObj;
+ }
+ virtual void clear() {
+ mObj.clear();
+ }
+private:
+ sp<IBinder> mObj;
+};
+
+//
+// A mock CameraClient
+//
+class MCameraClient : public BnCameraClient {
+public:
+ virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2);
+ virtual void dataCallback(int32_t msgType, const sp<IMemory>& data);
+ virtual void dataCallbackTimestamp(nsecs_t timestamp,
+ int32_t msgType, const sp<IMemory>& data) {}
+
+ // new functions
+ void clearStat();
+ enum OP { EQ, GE, LE, GT, LT };
+ void assertNotify(int32_t msgType, OP op, int count);
+ void assertData(int32_t msgType, OP op, int count);
+ void waitNotify(int32_t msgType, OP op, int count);
+ void waitData(int32_t msgType, OP op, int count);
+ void assertDataSize(int32_t msgType, OP op, int dataSize);
+
+ void setReleaser(ICamera *releaser) {
+ mReleaser = releaser;
+ }
+private:
+ Mutex mLock;
+ Condition mCond;
+ DefaultKeyedVector<int32_t, int> mNotifyCount;
+ DefaultKeyedVector<int32_t, int> mDataCount;
+ DefaultKeyedVector<int32_t, int> mDataSize;
+ bool test(OP op, int v1, int v2);
+
+ ICamera *mReleaser;
+};
+
+void MCameraClient::clearStat() {
+ Mutex::Autolock _l(mLock);
+ mNotifyCount.clear();
+ mDataCount.clear();
+ mDataSize.clear();
+}
+
+bool MCameraClient::test(OP op, int v1, int v2) {
+ switch (op) {
+ case EQ: return v1 == v2;
+ case GT: return v1 > v2;
+ case LT: return v1 < v2;
+ case GE: return v1 >= v2;
+ case LE: return v1 <= v2;
+ default: ASSERT(0); break;
+ }
+ return false;
+}
+
+void MCameraClient::assertNotify(int32_t msgType, OP op, int count) {
+ Mutex::Autolock _l(mLock);
+ int v = mNotifyCount.valueFor(msgType);
+ ASSERT(test(op, v, count));
+}
+
+void MCameraClient::assertData(int32_t msgType, OP op, int count) {
+ Mutex::Autolock _l(mLock);
+ int v = mDataCount.valueFor(msgType);
+ ASSERT(test(op, v, count));
+}
+
+void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) {
+ Mutex::Autolock _l(mLock);
+ int v = mDataSize.valueFor(msgType);
+ ASSERT(test(op, v, dataSize));
+}
+
+void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
+ INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ssize_t i = mNotifyCount.indexOfKey(msgType);
+ if (i < 0) {
+ mNotifyCount.add(msgType, 1);
+ } else {
+ ++mNotifyCount.editValueAt(i);
+ }
+ mCond.signal();
+}
+
+void MCameraClient::dataCallback(int32_t msgType, const sp<IMemory>& data) {
+ INFO(__func__);
+ int dataSize = data->size();
+ INFO("data type = %d, size = %d", msgType, dataSize);
+ Mutex::Autolock _l(mLock);
+ ssize_t i = mDataCount.indexOfKey(msgType);
+ if (i < 0) {
+ mDataCount.add(msgType, 1);
+ mDataSize.add(msgType, dataSize);
+ } else {
+ ++mDataCount.editValueAt(i);
+ mDataSize.editValueAt(i) = dataSize;
+ }
+ mCond.signal();
+
+ if (msgType == CAMERA_MSG_VIDEO_FRAME) {
+ ASSERT(mReleaser != NULL);
+ mReleaser->releaseRecordingFrame(data);
+ }
+}
+
+void MCameraClient::waitNotify(int32_t msgType, OP op, int count) {
+ INFO("waitNotify: %d, %d, %d", msgType, op, count);
+ Mutex::Autolock _l(mLock);
+ while (true) {
+ int v = mNotifyCount.valueFor(msgType);
+ if (test(op, v, count)) {
+ break;
+ }
+ mCond.wait(mLock);
+ }
+}
+
+void MCameraClient::waitData(int32_t msgType, OP op, int count) {
+ INFO("waitData: %d, %d, %d", msgType, op, count);
+ Mutex::Autolock _l(mLock);
+ while (true) {
+ int v = mDataCount.valueFor(msgType);
+ if (test(op, v, count)) {
+ break;
+ }
+ mCond.wait(mLock);
+ }
+}
+
+//
+// A mock Surface
+//
+class MSurface : public BnSurface {
+public:
+ virtual status_t registerBuffers(const BufferHeap& buffers);
+ virtual void postBuffer(ssize_t offset);
+ virtual void unregisterBuffers();
+ virtual sp<OverlayRef> createOverlay(
+ uint32_t w, uint32_t h, int32_t format);
+ virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
+
+ // new functions
+ void clearStat();
+ void waitUntil(int c0, int c1, int c2);
+
+private:
+ // check callback count
+ Condition mCond;
+ Mutex mLock;
+ int registerBuffersCount;
+ int postBufferCount;
+ int unregisterBuffersCount;
+};
+
+status_t MSurface::registerBuffers(const BufferHeap& buffers) {
+ INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ++registerBuffersCount;
+ mCond.signal();
+ return NO_ERROR;
+}
+
+void MSurface::postBuffer(ssize_t offset) {
+ // INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ++postBufferCount;
+ mCond.signal();
+}
+
+void MSurface::unregisterBuffers() {
+ INFO(__func__);
+ Mutex::Autolock _l(mLock);
+ ++unregisterBuffersCount;
+ mCond.signal();
+}
+
+sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
+ INFO(__func__);
+ return NULL;
+}
+
+void MSurface::clearStat() {
+ Mutex::Autolock _l(mLock);
+ registerBuffersCount = 0;
+ postBufferCount = 0;
+ unregisterBuffersCount = 0;
+}
+
+void MSurface::waitUntil(int c0, int c1, int c2) {
+ INFO("waitUntil: %d %d %d", c0, c1, c2);
+ Mutex::Autolock _l(mLock);
+ while (true) {
+ if (registerBuffersCount >= c0 &&
+ postBufferCount >= c1 &&
+ unregisterBuffersCount >= c2) {
+ break;
+ }
+ mCond.wait(mLock);
+ }
+}
+
+sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format) {
+ // We don't expect this to be called in current hardware.
+ ASSERT(0);
+ sp<OverlayRef> dummy;
+ return dummy;
+}
+
+//
+// Utilities to use the Holder service
+//
+sp<IHolder> getHolder() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ ASSERT(sm != 0);
+ sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder"));
+ ASSERT(binder != 0);
+ sp<IHolder> holder = interface_cast<IHolder>(binder);
+ ASSERT(holder != 0);
+ return holder;
+}
+
+void putTempObject(sp<IBinder> obj) {
+ INFO(__func__);
+ getHolder()->put(obj);
+}
+
+sp<IBinder> getTempObject() {
+ INFO(__func__);
+ return getHolder()->get();
+}
+
+void clearTempObject() {
+ INFO(__func__);
+ getHolder()->clear();
+}
+
+//
+// Get a Camera Service
+//
+sp<ICameraService> getCameraService() {
+ sp<IServiceManager> sm = defaultServiceManager();
+ ASSERT(sm != 0);
+ sp<IBinder> binder = sm->getService(String16("media.camera"));
+ ASSERT(binder != 0);
+ sp<ICameraService> cs = interface_cast<ICameraService>(binder);
+ ASSERT(cs != 0);
+ return cs;
+}
+
+//
+// Various Connect Tests
+//
+void testConnect() {
+ INFO(__func__);
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ c->disconnect();
+}
+
+void testAllowConnectOnceOnly() {
+ INFO(__func__);
+ sp<ICameraService> cs = getCameraService();
+ // Connect the first client.
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // Same client -- ok.
+ ASSERT(cs->connect(cc) != 0);
+ // Different client -- not ok.
+ sp<MCameraClient> cc2 = new MCameraClient();
+ ASSERT(cs->connect(cc2) == 0);
+ c->disconnect();
+}
+
+void testReconnectFailed() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ sp<MCameraClient> cc2 = new MCameraClient();
+ ASSERT(c->connect(cc2) != NO_ERROR);
+}
+
+void testReconnectSuccess() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ sp<MCameraClient> cc = new MCameraClient();
+ ASSERT(c->connect(cc) == NO_ERROR);
+}
+
+void testLockFailed() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ ASSERT(c->lock() != NO_ERROR);
+}
+
+void testLockUnlockSuccess() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ ASSERT(c->lock() == NO_ERROR);
+ ASSERT(c->unlock() == NO_ERROR);
+}
+
+void testLockSuccess() {
+ INFO(__func__);
+ sp<ICamera> c = interface_cast<ICamera>(getTempObject());
+ ASSERT(c->lock() == NO_ERROR);
+}
+
+//
+// Run the connect tests in another process.
+//
+const char *gExecutable;
+
+struct FunctionTableEntry {
+ const char *name;
+ void (*func)();
+};
+
+FunctionTableEntry function_table[] = {
+#define ENTRY(x) {#x, &x}
+ ENTRY(testReconnectFailed),
+ ENTRY(testReconnectSuccess),
+ ENTRY(testLockUnlockSuccess),
+ ENTRY(testLockFailed),
+ ENTRY(testLockSuccess),
+#undef ENTRY
+};
+
+void runFunction(const char *tag) {
+ INFO("runFunction: %s", tag);
+ int entries = sizeof(function_table) / sizeof(function_table[0]);
+ for (int i = 0; i < entries; i++) {
+ if (strcmp(function_table[i].name, tag) == 0) {
+ (*function_table[i].func)();
+ return;
+ }
+ }
+ ASSERT(0);
+}
+
+void runInAnotherProcess(const char *tag) {
+ pid_t pid = fork();
+ if (pid == 0) {
+ execlp(gExecutable, gExecutable, tag, NULL);
+ ASSERT(0);
+ } else {
+ int status;
+ ASSERT_EQ(pid, wait(&status));
+ ASSERT_EQ(0, status);
+ }
+}
+
+void testReconnect() {
+ INFO(__func__);
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // Reconnect to the same client -- ok.
+ ASSERT(c->connect(cc) == NO_ERROR);
+ // Reconnect to a different client (but the same pid) -- ok.
+ sp<MCameraClient> cc2 = new MCameraClient();
+ ASSERT(c->connect(cc2) == NO_ERROR);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+}
+
+void testLockUnlock() {
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // We can lock as many times as we want.
+ ASSERT(c->lock() == NO_ERROR);
+ ASSERT(c->lock() == NO_ERROR);
+ // Lock from a different process -- not ok.
+ putTempObject(c->asBinder());
+ runInAnotherProcess("testLockFailed");
+ // Unlock then lock from a different process -- ok.
+ ASSERT(c->unlock() == NO_ERROR);
+ runInAnotherProcess("testLockUnlockSuccess");
+ // Unlock then lock from a different process -- ok.
+ runInAnotherProcess("testLockSuccess");
+ c->disconnect();
+ clearTempObject();
+}
+
+void testReconnectFromAnotherProcess() {
+ INFO(__func__);
+
+ sp<ICameraService> cs = getCameraService();
+ sp<MCameraClient> cc = new MCameraClient();
+ sp<ICamera> c = cs->connect(cc);
+ ASSERT(c != 0);
+ // Reconnect from a different process -- not ok.
+ putTempObject(c->asBinder());
+ runInAnotherProcess("testReconnectFailed");
+ // Unlock then reconnect from a different process -- ok.
+ ASSERT(c->unlock() == NO_ERROR);
+ runInAnotherProcess("testReconnectSuccess");
+ c->disconnect();
+ clearTempObject();
+}
+
+// We need to flush the command buffer after the reference
+// to ICamera is gone. The sleep is for the server to run
+// the destructor for it.
+static void flushCommands() {
+ IPCThreadState::self()->flushCommands();
+ usleep(200000); // 200ms
+}
+
+// Run a test case
+#define RUN(class_name) do { \
+ { \
+ INFO(#class_name); \
+ class_name instance; \
+ instance.run(); \
+ } \
+ flushCommands(); \
+} while(0)
+
+// Base test case after the the camera is connected.
+class AfterConnect {
+protected:
+ sp<ICameraService> cs;
+ sp<MCameraClient> cc;
+ sp<ICamera> c;
+
+ AfterConnect() {
+ cs = getCameraService();
+ cc = new MCameraClient();
+ c = cs->connect(cc);
+ ASSERT(c != 0);
+ }
+
+ ~AfterConnect() {
+ c.clear();
+ cc.clear();
+ cs.clear();
+ }
+};
+
+class TestSetPreviewDisplay : public AfterConnect {
+public:
+ void run() {
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestStartPreview : public AfterConnect {
+public:
+ void run() {
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+
+ ASSERT(c->startPreview() == NO_ERROR);
+ ASSERT(c->previewEnabled() == true);
+
+ surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer
+ surface->clearStat();
+
+ c->disconnect();
+ // TODO: CameraService crashes for this. Fix it.
+#if 0
+ sp<MSurface> another_surface = new MSurface();
+ c->setPreviewDisplay(another_surface); // just to make sure unregisterBuffers
+ // is called.
+ surface->waitUntil(0, 0, 1); // needs unregisterBuffers
+#endif
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestStartPreviewWithoutDisplay : AfterConnect {
+public:
+ void run() {
+ ASSERT(c->startPreview() == NO_ERROR);
+ ASSERT(c->previewEnabled() == true);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+// Base test case after the the camera is connected and the preview is started.
+class AfterStartPreview : public AfterConnect {
+protected:
+ sp<MSurface> surface;
+
+ AfterStartPreview() {
+ surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+ ASSERT(c->startPreview() == NO_ERROR);
+ }
+
+ ~AfterStartPreview() {
+ surface.clear();
+ }
+};
+
+class TestAutoFocus : public AfterStartPreview {
+public:
+ void run() {
+ cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0);
+ c->autoFocus();
+ cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestStopPreview : public AfterStartPreview {
+public:
+ void run() {
+ ASSERT(c->previewEnabled() == true);
+ c->stopPreview();
+ ASSERT(c->previewEnabled() == false);
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestTakePicture: public AfterStartPreview {
+public:
+ void run() {
+ ASSERT(c->takePicture() == NO_ERROR);
+ cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+ c->stopPreview();
+#if 1 // TODO: It crashes if we don't have this. Fix it.
+ usleep(100000);
+#endif
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestTakeMultiplePictures: public AfterStartPreview {
+public:
+ void run() {
+ for (int i = 0; i < 10; i++) {
+ cc->clearStat();
+ ASSERT(c->takePicture() == NO_ERROR);
+ cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+ cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+ usleep(100000); // 100ms
+ }
+ c->disconnect();
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ }
+};
+
+class TestGetParameters: public AfterStartPreview {
+public:
+ void run() {
+ String8 param_str = c->getParameters();
+ INFO(param_str);
+ }
+};
+
+class TestPictureSize : public AfterStartPreview {
+public:
+ void checkOnePicture(int w, int h) {
+ const float rate = 0.5; // byte per pixel limit
+ int pixels = w * h;
+
+ CameraParameters param(c->getParameters());
+ param.setPictureSize(w, h);
+ c->setParameters(param.flatten());
+
+ cc->clearStat();
+ ASSERT(c->takePicture() == NO_ERROR);
+ cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
+ cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2);
+ cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
+ cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT,
+ int(pixels * rate));
+ cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0);
+ cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
+ usleep(100000); // 100ms
+ }
+
+ void run() {
+ checkOnePicture(2048, 1536);
+ checkOnePicture(1600, 1200);
+ checkOnePicture(1024, 768);
+ }
+};
+
+class TestPreviewCallbackFlag : public AfterConnect {
+public:
+ void run() {
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+
+ // Try all flag combinations.
+ for (int v = 0; v < 8; v++) {
+ cc->clearStat();
+ c->setPreviewCallbackFlag(v);
+ ASSERT(c->previewEnabled() == false);
+ ASSERT(c->startPreview() == NO_ERROR);
+ ASSERT(c->previewEnabled() == true);
+ sleep(2);
+ c->stopPreview();
+ if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
+ cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
+ } else {
+ if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
+ cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
+ } else {
+ cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
+ }
+ }
+ }
+ }
+};
+
+class TestRecording : public AfterConnect {
+public:
+ void run() {
+ ASSERT(c->recordingEnabled() == false);
+ sp<MSurface> surface = new MSurface();
+ ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
+ c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ cc->setReleaser(c.get());
+ c->startRecording();
+ ASSERT(c->recordingEnabled() == true);
+ sleep(2);
+ c->stopRecording();
+ cc->setReleaser(NULL);
+ cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10);
+ }
+};
+
+class TestPreviewSize : public AfterStartPreview {
+public:
+ void checkOnePicture(int w, int h) {
+ int size = w*h*3/2; // should read from parameters
+
+ c->stopPreview();
+
+ CameraParameters param(c->getParameters());
+ param.setPreviewSize(w, h);
+ c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
+ c->setParameters(param.flatten());
+
+ c->startPreview();
+
+ cc->clearStat();
+ cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1);
+ cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size);
+ }
+
+ void run() {
+ checkOnePicture(480, 320);
+ checkOnePicture(352, 288);
+ checkOnePicture(176, 144);
+ }
+};
+
+void runHolderService() {
+ defaultServiceManager()->addService(
+ String16("CameraServiceTest.Holder"), new HolderService());
+ ProcessState::self()->startThreadPool();
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 1) {
+ runFunction(argv[1]);
+ return 0;
+ }
+ INFO("CameraServiceTest start");
+ gExecutable = argv[0];
+ runHolderService();
+
+ testConnect(); flushCommands();
+ testAllowConnectOnceOnly(); flushCommands();
+ testReconnect(); flushCommands();
+ testLockUnlock(); flushCommands();
+ testReconnectFromAnotherProcess(); flushCommands();
+
+ RUN(TestSetPreviewDisplay);
+ RUN(TestStartPreview);
+ RUN(TestStartPreviewWithoutDisplay);
+ RUN(TestAutoFocus);
+ RUN(TestStopPreview);
+ RUN(TestTakePicture);
+ RUN(TestTakeMultiplePictures);
+ RUN(TestGetParameters);
+ RUN(TestPictureSize);
+ RUN(TestPreviewCallbackFlag);
+ RUN(TestRecording);
+ RUN(TestPreviewSize);
+}
diff --git a/include/binder/IBinder.h b/include/binder/IBinder.h
index 884b5c1..749a977 100644
--- a/include/binder/IBinder.h
+++ b/include/binder/IBinder.h
@@ -52,7 +52,7 @@
DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'),
INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
- // Corresponds to tfOneWay -- an asynchronous call.
+ // Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001
};
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 78306b2..3ab985d 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -68,6 +68,13 @@
static void shutdown();
+ // Call this to disable switching threads to background scheduling when
+ // receiving incoming IPC calls. This is specifically here for the
+ // Android system process, since it expects to have background apps calling
+ // in to it but doesn't want to acquire locks in its services while in
+ // the background.
+ static void disableBackgroundScheduling(bool disable);
+
private:
IPCThreadState();
~IPCThreadState();
@@ -93,9 +100,10 @@
void* cookie);
const sp<ProcessState> mProcess;
+ const pid_t mMyThreadId;
Vector<BBinder*> mPendingStrongDerefs;
Vector<RefBase::weakref_type*> mPendingWeakDerefs;
-
+
Parcel mIn;
Parcel mOut;
status_t mLastError;
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 49145e8..a845908 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -393,7 +393,10 @@
enum {
// If set, the string index is sorted by the string values (based
// on strcmp16()).
- SORTED_FLAG = 1<<0
+ SORTED_FLAG = 1<<0,
+
+ // String pool is encoded in UTF-8
+ UTF8_FLAG = 1<<8
};
uint32_t flags;
@@ -456,9 +459,11 @@
void* mOwnedData;
const ResStringPool_header* mHeader;
size_t mSize;
+ mutable Mutex mDecodeLock;
const uint32_t* mEntries;
const uint32_t* mEntryStyles;
- const char16_t* mStrings;
+ const void* mStrings;
+ char16_t** mCache;
uint32_t mStringPoolSize; // number of uint16_t
const uint32_t* mStyles;
uint32_t mStylePoolSize; // number of uint32_t
diff --git a/include/utils/String16.h b/include/utils/String16.h
index a2d22ee..07a0c11 100644
--- a/include/utils/String16.h
+++ b/include/utils/String16.h
@@ -49,12 +49,17 @@
// Version of strzcmp16 for comparing strings in different endianness.
int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
+// Convert UTF-8 to UTF-16 including surrogate pairs
+void utf8_to_utf16(const uint8_t *src, size_t srcLen, char16_t* dst, const size_t dstLen);
+
}
// ---------------------------------------------------------------------------
namespace android {
+// ---------------------------------------------------------------------------
+
class String8;
class TextOutput;
diff --git a/include/utils/String8.h b/include/utils/String8.h
index ecc5774..c4b18a4 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -60,6 +60,11 @@
/*
* Returns the UTF-8 length of "src".
*/
+size_t utf8_length_from_utf16(const char16_t *src, size_t src_len);
+
+/*
+ * Returns the UTF-8 length of "src".
+ */
size_t utf8_length_from_utf32(const char32_t *src, size_t src_len);
/*
@@ -120,6 +125,9 @@
size_t utf32_to_utf8(const char32_t* src, size_t src_len,
char* dst, size_t dst_len);
+size_t utf16_to_utf8(const char16_t* src, size_t src_len,
+ char* dst, size_t dst_len);
+
}
// ---------------------------------------------------------------------------
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 0fc533f..130d83c 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -124,6 +124,24 @@
extern void androidSetCreateThreadFunc(android_create_thread_fn func);
+// ------------------------------------------------------------------
+// Extra functions working with raw pids.
+
+// Get pid for the current thread.
+extern pid_t androidGetTid();
+
+// Change the scheduling group of a particular thread. The group
+// should be one of the ANDROID_TGROUP constants. Returns BAD_VALUE if
+// grp is out of range, else another non-zero value with errno set if
+// the operation failed.
+extern int androidSetThreadSchedulingGroup(pid_t tid, int grp);
+
+// Change the priority AND scheduling group of a particular thread. The priority
+// should be one of the ANDROID_PRIORITY constants. Returns INVALID_OPERATION
+// if the priority set failed, else another value if just the group set failed;
+// in either case errno is set.
+extern int androidSetThreadPriority(pid_t tid, int prio);
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index daec6e8..2024cc0 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1111,7 +1111,6 @@
{
track->mState = TrackBase::TERMINATED;
if (mActiveTracks.indexOf(track) < 0) {
- LOGV("remove track (%d) and delete from mixer", track->name());
mTracks.remove(track);
deleteTrackName_l(track->name());
}
@@ -1511,6 +1510,7 @@
// deleteTrackName_l() must be called with ThreadBase::mLock held
void AudioFlinger::MixerThread::deleteTrackName_l(int name)
{
+ LOGV("remove track (%d) and delete from mixer", name);
mAudioMixer->deleteTrackName(name);
}
@@ -1922,6 +1922,9 @@
AudioFlinger::DuplicatingThread::~DuplicatingThread()
{
+ for (size_t i = 0; i < mOutputTracks.size(); i++) {
+ mOutputTracks[i]->destroy();
+ }
mOutputTracks.clear();
}
@@ -2044,17 +2047,6 @@
outputTracks.clear();
}
- { // scope for the mLock
-
- Mutex::Autolock _l(mLock);
- if (!mStandby) {
- LOGV("DuplicatingThread() exiting out of standby");
- for (size_t i = 0; i < mOutputTracks.size(); i++) {
- mOutputTracks[i]->destroy();
- }
- }
- }
-
return false;
}
@@ -2277,10 +2269,8 @@
LOGV("PlaybackThread::Track destructor");
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- thread->mLock.lock();
+ Mutex::Autolock _l(thread->mLock);
mState = TERMINATED;
- thread->mLock.unlock();
- AudioSystem::releaseOutput(thread->id());
}
}
@@ -2298,8 +2288,11 @@
{ // scope for mLock
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- if (!isOutputTrack() && (mState == ACTIVE || mState == RESUMING)) {
- AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ if (!isOutputTrack()) {
+ if (mState == ACTIVE || mState == RESUMING) {
+ AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ }
+ AudioSystem::releaseOutput(thread->id());
}
Mutex::Autolock _l(thread->mLock);
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
@@ -3085,23 +3078,34 @@
}
if (mActiveTrack != 0) {
if (mActiveTrack->mState == TrackBase::PAUSING) {
+ if (!mStandby) {
+ mInput->standby();
+ mStandby = true;
+ }
mActiveTrack.clear();
mStartStopCond.broadcast();
} else if (mActiveTrack->mState == TrackBase::RESUMING) {
- mRsmpInIndex = mFrameCount;
if (mReqChannelCount != mActiveTrack->channelCount()) {
mActiveTrack.clear();
- } else {
- mActiveTrack->mState = TrackBase::ACTIVE;
+ mStartStopCond.broadcast();
+ } else if (mBytesRead != 0) {
+ // record start succeeds only if first read from audio input
+ // succeeds
+ if (mBytesRead > 0) {
+ mActiveTrack->mState = TrackBase::ACTIVE;
+ } else {
+ mActiveTrack.clear();
+ }
+ mStartStopCond.broadcast();
}
- mStartStopCond.broadcast();
+ mStandby = false;
}
- mStandby = false;
}
}
if (mActiveTrack != 0) {
- if (mActiveTrack->mState != TrackBase::ACTIVE) {
+ if (mActiveTrack->mState != TrackBase::ACTIVE &&
+ mActiveTrack->mState != TrackBase::RESUMING) {
usleep(5000);
continue;
}
@@ -3139,18 +3143,19 @@
}
}
if (framesOut && mFrameCount == mRsmpInIndex) {
- ssize_t bytesRead;
if (framesOut == mFrameCount &&
(mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
- bytesRead = mInput->read(buffer.raw, mInputBytes);
+ mBytesRead = mInput->read(buffer.raw, mInputBytes);
framesOut = 0;
} else {
- bytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+ mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
mRsmpInIndex = 0;
}
- if (bytesRead < 0) {
+ if (mBytesRead < 0) {
LOGE("Error reading audio input");
- sleep(1);
+ if (mActiveTrack->mState == TrackBase::ACTIVE) {
+ sleep(1);
+ }
mRsmpInIndex = mFrameCount;
framesOut = 0;
buffer.frameCount = 0;
@@ -3219,7 +3224,7 @@
if (recordTrack != mActiveTrack.get()) {
status = -EBUSY;
} else if (mActiveTrack->mState == TrackBase::PAUSING) {
- mActiveTrack->mState = TrackBase::RESUMING;
+ mActiveTrack->mState = TrackBase::ACTIVE;
}
return status;
}
@@ -3234,6 +3239,8 @@
return status;
}
mActiveTrack->mState = TrackBase::RESUMING;
+ mRsmpInIndex = mFrameCount;
+ mBytesRead = 0;
// signal thread to start
LOGV("Signal record thread");
mWaitWorkCV.signal();
@@ -3274,6 +3281,7 @@
mLock.unlock();
AudioSystem::stopInput(mId);
mLock.lock();
+ LOGV("Record stopped OK");
}
}
}
@@ -3324,10 +3332,12 @@
int channelCount;
if (framesReady == 0) {
- ssize_t bytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
- if (bytesRead < 0) {
+ mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
+ if (mBytesRead < 0) {
LOGE("RecordThread::getNextBuffer() Error reading audio input");
- sleep(1);
+ if (mActiveTrack->mState == TrackBase::ACTIVE) {
+ sleep(1);
+ }
buffer->raw = 0;
buffer->frameCount = 0;
return NOT_ENOUGH_DATA;
@@ -3545,9 +3555,11 @@
if (pFormat) *pFormat = format;
if (pChannels) *pChannels = channels;
if (pLatencyMs) *pLatencyMs = thread->latency();
+
+ return mNextThreadId;
}
- return mNextThreadId;
+ return 0;
}
int AudioFlinger::openDuplicateOutput(int output1, int output2)
@@ -3693,9 +3705,11 @@
if (pChannels) *pChannels = reqChannels;
input->standby();
+
+ return mNextThreadId;
}
- return mNextThreadId;
+ return 0;
}
status_t AudioFlinger::closeInput(int input)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 5a17294..8c29da8 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -744,6 +744,7 @@
size_t mInputBytes;
int mReqChannelCount;
uint32_t mReqSampleRate;
+ ssize_t mBytesRead;
};
class RecordHandle : public android::BnAudioRecord {
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b2a7db8..473f580 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -292,6 +292,7 @@
static bool gHaveTLS = false;
static pthread_key_t gTLS = 0;
static bool gShutdown = false;
+static bool gDisableBackgroundScheduling = false;
IPCThreadState* IPCThreadState::self()
{
@@ -332,6 +333,11 @@
}
}
+void IPCThreadState::disableBackgroundScheduling(bool disable)
+{
+ gDisableBackgroundScheduling = disable;
+}
+
sp<ProcessState> IPCThreadState::process()
{
return mProcess;
@@ -386,6 +392,11 @@
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
+ // This thread may have been spawned by a thread that was in the background
+ // scheduling group, so first we will make sure it is in the default/foreground
+ // one to avoid performing an initial transaction in the background.
+ androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+
status_t result;
do {
int32_t cmd;
@@ -427,19 +438,13 @@
}
// After executing the command, ensure that the thread is returned to the
- // default cgroup and priority before rejoining the pool. This is a failsafe
- // in case the command implementation failed to properly restore the thread's
- // scheduling parameters upon completion.
- int my_id;
-#ifdef HAVE_GETTID
- my_id = gettid();
-#else
- my_id = getpid();
-#endif
- if (!set_sched_policy(my_id, SP_FOREGROUND)) {
- // success; reset the priority as well
- setpriority(PRIO_PROCESS, my_id, ANDROID_PRIORITY_NORMAL);
- }
+ // default cgroup before rejoining the pool. The driver takes care of
+ // restoring the priority, but doesn't do anything with cgroups so we
+ // need to take care of that here in userspace. Note that we do make
+ // sure to go in the foreground after executing a transaction, but
+ // there are other callbacks into user code that could have changed
+ // our group so we want to make absolutely sure it is put back.
+ androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
// Let this thread exit the thread pool if it is no longer
// needed and it is not the main process thread.
@@ -583,10 +588,10 @@
}
IPCThreadState::IPCThreadState()
- : mProcess(ProcessState::self())
+ : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
{
pthread_setspecific(gTLS, this);
- clearCaller();
+ clearCaller();
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
@@ -930,6 +935,17 @@
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
+ bool doBackground = !gDisableBackgroundScheduling &&
+ getpriority(PRIO_PROCESS, mMyThreadId)
+ >= ANDROID_PRIORITY_BACKGROUND;
+ if (doBackground) {
+ // We have inherited a background priority from the caller.
+ // Ensure this thread is in the background scheduling class,
+ // since the driver won't modify scheduling classes for us.
+ androidSetThreadSchedulingGroup(mMyThreadId,
+ ANDROID_TGROUP_BG_NONINTERACT);
+ }
+
//LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
Parcel reply;
@@ -967,6 +983,13 @@
mCallingPid = origPid;
mCallingUid = origUid;
+ if (doBackground) {
+ // We moved to the background scheduling group to execute
+ // this transaction, so now that we are done go back in the
+ // foreground.
+ androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT);
+ }
+
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index eb51c22..b3fed58 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -22,9 +22,6 @@
ifeq ($(TARGET_BOARD_PLATFORM), msm7k)
LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
endif
-ifeq ($(TARGET_BOARD_PLATFORM), qsd8k)
- LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
-endif
# need "-lrt" on Linux simulator to pick up clock_gettime
ifeq ($(TARGET_SIMULATOR),true)
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 79c003f..d9d9bfe 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -246,8 +246,7 @@
LOGI("version : %s", glGetString(GL_VERSION));
LOGI("extensions: %s", gl_extensions);
- if (strstr(gl_renderer, "PowerVR SGX 530") ||
- strstr(gl_renderer, "Adreno")) {
+ if (strstr(gl_renderer, "Adreno")) {
LOGD("Assuming uncached graphics buffers.");
mFlags &= ~CACHED_BUFFERS;
}
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index f5a5a0b..f11bf18 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -515,6 +515,11 @@
dirtyRegion.andSelf(visibleRegionScreen);
outDirtyRegion.orSelf(dirtyRegion);
}
+ if (visibleRegionScreen.isEmpty()) {
+ // an invisible layer should not hold a freeze-lock
+ // (because it may never be updated and thereore never release it)
+ mFreezeLock.clear();
+ }
}
void Layer::finishPageFlip()
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 88ef7e4..eb017bf 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -266,7 +266,16 @@
: mBufferHeap(buffers)
{
NativeBuffer& src(mNativeBuffer);
- src.img.handle = 0;
+ src.crop.l = 0;
+ src.crop.t = 0;
+ src.crop.r = buffers.w;
+ src.crop.b = buffers.h;
+
+ src.img.w = buffers.hor_stride ?: buffers.w;
+ src.img.h = buffers.ver_stride ?: buffers.h;
+ src.img.format = buffers.format;
+ src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
+ src.img.handle = 0;
gralloc_module_t const * module = LayerBuffer::getGrallocModule();
if (module && module->perform) {
@@ -276,19 +285,12 @@
offset, buffers.heap->base(),
&src.img.handle);
- if (err == NO_ERROR) {
- src.crop.l = 0;
- src.crop.t = 0;
- src.crop.r = buffers.w;
- src.crop.b = buffers.h;
-
- src.img.w = buffers.hor_stride ?: buffers.w;
- src.img.h = buffers.ver_stride ?: buffers.h;
- src.img.format = buffers.format;
- src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
- }
+ LOGE_IF(err, "CREATE_HANDLE_FROM_BUFFER (heapId=%d, size=%d, "
+ "offset=%ld, base=%p) failed (%s)",
+ buffers.heap->heapID(), buffers.heap->getSize(),
+ offset, buffers.heap->base(), strerror(-err));
}
-}
+ }
LayerBuffer::Buffer::~Buffer()
{
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 9694cf1..965b7dd 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -417,9 +417,9 @@
{
while (true) {
nsecs_t timeout = -1;
+ const nsecs_t freezeDisplayTimeout = ms2ns(5000);
if (UNLIKELY(isFrozen())) {
// wait 5 seconds
- const nsecs_t freezeDisplayTimeout = ms2ns(5000);
const nsecs_t now = systemTime();
if (mFreezeDisplayTime == 0) {
mFreezeDisplayTime = now;
@@ -429,23 +429,27 @@
}
MessageList::value_type msg = mEventQueue.waitMessage(timeout);
+
+ // see if we timed out
+ if (isFrozen()) {
+ const nsecs_t now = systemTime();
+ nsecs_t frozenTime = (now - mFreezeDisplayTime);
+ if (frozenTime >= freezeDisplayTimeout) {
+ // we timed out and are still frozen
+ LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+ mFreezeDisplay, mFreezeCount);
+ mFreezeDisplayTime = 0;
+ mFreezeCount = 0;
+ mFreezeDisplay = false;
+ }
+ }
+
if (msg != 0) {
- mFreezeDisplayTime = 0;
switch (msg->what) {
case MessageQueue::INVALIDATE:
// invalidate message, just return to the main loop
return;
}
- } else {
- // we timed out
- if (isFrozen()) {
- // we timed out and are still frozen
- LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
- mFreezeDisplay, mFreezeCount);
- mFreezeCount = 0;
- mFreezeDisplay = false;
- return;
- }
}
}
}
@@ -1646,6 +1650,7 @@
}
case 1007: // set mFreezeCount
mFreezeCount = data.readInt32();
+ mFreezeDisplayTime = 0;
return NO_ERROR;
case 1010: // interrogate.
reply->writeInt32(0);
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index f9bfe6c..c0ab73d 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -291,7 +291,11 @@
friend class FreezeLock;
sp<FreezeLock> getFreezeLock() const;
- inline void incFreezeCount() { mFreezeCount++; }
+ inline void incFreezeCount() {
+ if (mFreezeCount == 0)
+ mFreezeDisplayTime = 0;
+ mFreezeCount++;
+ }
inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
inline bool hasFreezeRequest() const { return mFreezeDisplay; }
inline bool isFrozen() const {
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 450af8d..afca814 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -229,12 +229,12 @@
// --------------------------------------------------------------------
ResStringPool::ResStringPool()
- : mError(NO_INIT), mOwnedData(NULL)
+ : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
{
}
ResStringPool::ResStringPool(const void* data, size_t size, bool copyData)
- : mError(NO_INIT), mOwnedData(NULL)
+ : mError(NO_INIT), mOwnedData(NULL), mHeader(NULL), mCache(NULL)
{
setTo(data, size, copyData);
}
@@ -296,7 +296,17 @@
(int)size);
return (mError=BAD_TYPE);
}
- mStrings = (const char16_t*)
+
+ size_t charSize;
+ if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
+ charSize = sizeof(uint8_t);
+ mCache = (char16_t**)malloc(sizeof(char16_t**)*mHeader->stringCount);
+ memset(mCache, 0, sizeof(char16_t**)*mHeader->stringCount);
+ } else {
+ charSize = sizeof(char16_t);
+ }
+
+ mStrings = (const void*)
(((const uint8_t*)data)+mHeader->stringsStart);
if (mHeader->stringsStart >= (mHeader->header.size-sizeof(uint16_t))) {
LOGW("Bad string block: string pool starts at %d, after total size %d\n",
@@ -305,7 +315,7 @@
}
if (mHeader->styleCount == 0) {
mStringPoolSize =
- (mHeader->header.size-mHeader->stringsStart)/sizeof(uint16_t);
+ (mHeader->header.size-mHeader->stringsStart)/charSize;
} else {
// check invariant: styles follow the strings
if (mHeader->stylesStart <= mHeader->stringsStart) {
@@ -314,7 +324,7 @@
return (mError=BAD_TYPE);
}
mStringPoolSize =
- (mHeader->stylesStart-mHeader->stringsStart)/sizeof(uint16_t);
+ (mHeader->stylesStart-mHeader->stringsStart)/charSize;
}
// check invariant: stringCount > 0 requires a string pool to exist
@@ -329,13 +339,19 @@
for (i=0; i<mHeader->stringCount; i++) {
e[i] = dtohl(mEntries[i]);
}
- char16_t* s = const_cast<char16_t*>(mStrings);
- for (i=0; i<mStringPoolSize; i++) {
- s[i] = dtohs(mStrings[i]);
+ if (!(mHeader->flags&ResStringPool_header::UTF8_FLAG)) {
+ const char16_t* strings = (const char16_t*)mStrings;
+ char16_t* s = const_cast<char16_t*>(strings);
+ for (i=0; i<mStringPoolSize; i++) {
+ s[i] = dtohs(strings[i]);
+ }
}
}
- if (mStrings[mStringPoolSize-1] != 0) {
+ if ((mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+ ((uint8_t*)mStrings)[mStringPoolSize-1] != 0) ||
+ (!mHeader->flags&ResStringPool_header::UTF8_FLAG &&
+ ((char16_t*)mStrings)[mStringPoolSize-1] != 0)) {
LOGW("Bad string block: last string is not 0-terminated\n");
return (mError=BAD_TYPE);
}
@@ -410,24 +426,67 @@
free(mOwnedData);
mOwnedData = NULL;
}
+ if (mHeader != NULL && mCache != NULL) {
+ for (size_t x = 0; x < mHeader->stringCount; x++) {
+ if (mCache[x] != NULL) {
+ free(mCache[x]);
+ mCache[x] = NULL;
+ }
+ }
+ free(mCache);
+ mCache = NULL;
+ }
}
+#define DECODE_LENGTH(str, chrsz, len) \
+ len = *(str); \
+ if (*(str)&(1<<(chrsz*8-1))) { \
+ (str)++; \
+ len = (((len)&((1<<(chrsz*8-1))-1))<<(chrsz*8)) + *(str); \
+ } \
+ (str)++;
+
const uint16_t* ResStringPool::stringAt(size_t idx, size_t* outLen) const
{
if (mError == NO_ERROR && idx < mHeader->stringCount) {
- const uint32_t off = (mEntries[idx]/sizeof(uint16_t));
+ const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
+ const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
if (off < (mStringPoolSize-1)) {
- const char16_t* str = mStrings+off;
- *outLen = *str;
- if ((*str)&0x8000) {
- str++;
- *outLen = (((*outLen)&0x7fff)<<16) + *str;
- }
- if ((uint32_t)(str+1+*outLen-mStrings) < mStringPoolSize) {
- return str+1;
+ if (!isUTF8) {
+ const char16_t* strings = (char16_t*)mStrings;
+ const char16_t* str = strings+off;
+ DECODE_LENGTH(str, sizeof(char16_t), *outLen)
+ if ((uint32_t)(str+*outLen-strings) < mStringPoolSize) {
+ return str;
+ } else {
+ LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+ (int)idx, (int)(str+*outLen-strings), (int)mStringPoolSize);
+ }
} else {
- LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
- (int)idx, (int)(str+1+*outLen-mStrings), (int)mStringPoolSize);
+ const uint8_t* strings = (uint8_t*)mStrings;
+ const uint8_t* str = strings+off;
+ DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
+ size_t encLen;
+ DECODE_LENGTH(str, sizeof(uint8_t), encLen)
+ if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+ AutoMutex lock(mDecodeLock);
+ if (mCache[idx] != NULL) {
+ return mCache[idx];
+ }
+ char16_t *u16str = (char16_t *)calloc(*outLen+1, sizeof(char16_t));
+ if (!u16str) {
+ LOGW("No memory when trying to allocate decode cache for string #%d\n",
+ (int)idx);
+ return NULL;
+ }
+ const unsigned char *u8src = reinterpret_cast<const unsigned char *>(str);
+ utf8_to_utf16(u8src, encLen, u16str, *outLen);
+ mCache[idx] = u16str;
+ return u16str;
+ } else {
+ LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+ (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
+ }
}
} else {
LOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
@@ -466,6 +525,10 @@
size_t len;
+ // TODO optimize searching for UTF-8 strings taking into account
+ // the cache fill to determine when to convert the searched-for
+ // string key to UTF-8.
+
if (mHeader->flags&ResStringPool_header::SORTED_FLAG) {
// Do a binary search for the string...
ssize_t l = 0;
@@ -1043,6 +1106,7 @@
void ResXMLTree::uninit()
{
mError = NO_INIT;
+ mStrings.uninit();
if (mOwnedData) {
free(mOwnedData);
mOwnedData = NULL;
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index aef67f2..eab7b2b 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -172,10 +172,6 @@
: 0);
}
-// ---------------------------------------------------------------------------
-
-namespace android {
-
static inline size_t
utf8_char_len(uint8_t ch)
{
@@ -215,8 +211,38 @@
//printf("Char at %p: len=%d, utf-16=%p\n", src, length, (void*)result);
}
+void
+utf8_to_utf16(const uint8_t *src, size_t srcLen,
+ char16_t* dst, const size_t dstLen)
+{
+ const uint8_t* const end = src + srcLen;
+ const char16_t* const dstEnd = dst + dstLen;
+ while (src < end && dst < dstEnd) {
+ size_t len = utf8_char_len(*src);
+ uint32_t codepoint = utf8_to_utf32((const uint8_t*)src, len);
+
+ // Convert the UTF32 codepoint to one or more UTF16 codepoints
+ if (codepoint <= 0xFFFF) {
+ // Single UTF16 character
+ *dst++ = (char16_t) codepoint;
+ } else {
+ // Multiple UTF16 characters with surrogates
+ codepoint = codepoint - 0x10000;
+ *dst++ = (char16_t) ((codepoint >> 10) + 0xD800);
+ *dst++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+ }
+
+ src += len;
+ }
+ if (dst < dstEnd) {
+ *dst = 0;
+ }
+}
+
// ---------------------------------------------------------------------------
+namespace android {
+
static SharedBuffer* gEmptyStringBuf = NULL;
static char16_t* gEmptyString = NULL;
@@ -260,30 +286,14 @@
p += utf8len;
}
- SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
+ size_t bufSize = (chars+1)*sizeof(char16_t);
+ SharedBuffer* buf = SharedBuffer::alloc(bufSize);
if (buf) {
p = in;
char16_t* str = (char16_t*)buf->data();
- char16_t* d = str;
- while (p < end) {
- size_t len = utf8_char_len(*p);
- uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, len);
-
- // Convert the UTF32 codepoint to one or more UTF16 codepoints
- if (codepoint <= 0xFFFF) {
- // Single UTF16 character
- *d++ = (char16_t) codepoint;
- } else {
- // Multiple UTF16 characters with surrogates
- codepoint = codepoint - 0x10000;
- *d++ = (char16_t) ((codepoint >> 10) + 0xD800);
- *d++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
- }
-
- p += len;
- }
- *d = 0;
+ utf8_to_utf16((const uint8_t*)p, len, str, bufSize);
+
//printf("Created UTF-16 string from UTF-8 \"%s\":", in);
//printHexData(1, str, buf->size(), 16, 1);
//printf("\n");
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index e908ec1..3a34838 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -208,10 +208,23 @@
return getEmptyString();
}
-// Note: not dealing with expanding surrogate pairs.
static char* allocFromUTF16(const char16_t* in, size_t len)
{
- return allocFromUTF16OrUTF32<char16_t, size_t>(in, len);
+ if (len == 0) return getEmptyString();
+
+ const size_t bytes = utf8_length_from_utf16(in, len);
+
+ SharedBuffer* buf = SharedBuffer::alloc(bytes+1);
+ LOG_ASSERT(buf, "Unable to allocate shared buffer");
+ if (buf) {
+ char* str = (char*)buf->data();
+
+ utf16_to_utf8(in, len, str, bytes+1);
+
+ return str;
+ }
+
+ return getEmptyString();
}
static char* allocFromUTF32(const char32_t* in, size_t len)
@@ -762,6 +775,26 @@
return ret;
}
+size_t utf8_length_from_utf16(const char16_t *src, size_t src_len)
+{
+ if (src == NULL || src_len == 0) {
+ return 0;
+ }
+ size_t ret = 0;
+ const char16_t* const end = src + src_len;
+ while (src < end) {
+ if ((*src & 0xFC00) == 0xD800 && (src + 1) < end
+ && (*++src & 0xFC00) == 0xDC00) {
+ // surrogate pairs are always 4 bytes.
+ ret += 4;
+ src++;
+ } else {
+ ret += android::utf32_to_utf8_bytes((char32_t) *src++);
+ }
+ }
+ return ret;
+}
+
static int32_t utf32_at_internal(const char* cur, size_t *num_read)
{
const char first_char = *cur;
@@ -848,3 +881,33 @@
}
return cur - dst;
}
+
+size_t utf16_to_utf8(const char16_t* src, size_t src_len,
+ char* dst, size_t dst_len)
+{
+ if (src == NULL || src_len == 0 || dst == NULL || dst_len == 0) {
+ return 0;
+ }
+ const char16_t* cur_utf16 = src;
+ const char16_t* const end_utf16 = src + src_len;
+ char *cur = dst;
+ const char* const end = dst + dst_len;
+ while (cur_utf16 < end_utf16 && cur < end) {
+ char32_t utf32;
+ // surrogate pairs
+ if ((*cur_utf16 & 0xFC00) == 0xD800 && (cur_utf16 + 1) < end_utf16) {
+ utf32 = (*cur_utf16++ - 0xD800) << 10;
+ utf32 |= *cur_utf16++ - 0xDC00;
+ utf32 += 0x10000;
+ } else {
+ utf32 = (char32_t) *cur_utf16++;
+ }
+ size_t len = android::utf32_to_utf8_bytes(utf32);
+ android::utf32_to_utf8((uint8_t*)cur, utf32, len);
+ cur += len;
+ }
+ if (cur < end) {
+ *cur = '\0';
+ }
+ return cur - dst;
+}
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index ec3db09..2b1f490 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -20,6 +20,8 @@
#include <utils/threads.h>
#include <utils/Log.h>
+#include <cutils/sched_policy.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
@@ -269,6 +271,58 @@
gCreateThreadFn = func;
}
+pid_t androidGetTid()
+{
+#ifdef HAVE_GETTID
+ return gettid();
+#else
+ return getpid();
+#endif
+}
+
+int androidSetThreadSchedulingGroup(pid_t tid, int grp)
+{
+ if (grp > ANDROID_TGROUP_MAX || grp < 0) {
+ return BAD_VALUE;
+ }
+
+#if defined(HAVE_PTHREADS)
+ if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+ SP_BACKGROUND : SP_FOREGROUND)) {
+ return PERMISSION_DENIED;
+ }
+#endif
+
+ return NO_ERROR;
+}
+
+int androidSetThreadPriority(pid_t tid, int pri)
+{
+ int rc = 0;
+
+#if defined(HAVE_PTHREADS)
+ int lasterr = 0;
+
+ if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+ rc = set_sched_policy(tid, SP_BACKGROUND);
+ } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+ rc = set_sched_policy(tid, SP_FOREGROUND);
+ }
+
+ if (rc) {
+ lasterr = errno;
+ }
+
+ if (setpriority(PRIO_PROCESS, tid, pri) < 0) {
+ rc = INVALID_OPERATION;
+ } else {
+ errno = lasterr;
+ }
+#endif
+
+ return rc;
+}
+
namespace android {
/*
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index a68750e..4cacc11 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -38,7 +38,7 @@
#include <ui/Rect.h>
-#define DEBUG_COPYBIT true
+#define DEBUG_COPYBIT false
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 0c9352e..e7757a8 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -47,6 +47,12 @@
GLsizei stride, const GLvoid *pointer, GLsizei count);
GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count);
}
void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
@@ -66,6 +72,21 @@
glVertexPointer(size, type, stride, pointer);
}
+void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glPointSizePointerOES(type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glMatrixIndexPointerOES(size, type, stride, pointer);
+}
+
+GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glWeightPointerOES(size, type, stride, pointer);
+}
+
// ----------------------------------------------------------------------------
// Actual GL entry-points
// ----------------------------------------------------------------------------
diff --git a/opengl/tests/gl2_java/Android.mk b/opengl/tests/gl2_java/Android.mk
new file mode 100644
index 0000000..34f4aee
--- /dev/null
+++ b/opengl/tests/gl2_java/Android.mk
@@ -0,0 +1,18 @@
+#########################################################################
+# OpenGL ES 2.0 Java sample
+#########################################################################
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GL2Java
+
+include $(BUILD_PACKAGE)
diff --git a/opengl/tests/gl2_java/AndroidManifest.xml b/opengl/tests/gl2_java/AndroidManifest.xml
new file mode 100644
index 0000000..585b63f
--- /dev/null
+++ b/opengl/tests/gl2_java/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** 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.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.gl2java">
+ <uses-feature android:glEsVersion="0x00020000" />
+ <application
+ android:label="@string/gl2java_activity">
+ <activity android:name="GL2JavaActivity"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/opengl/tests/gl2_java/res/values/strings.xml b/opengl/tests/gl2_java/res/values/strings.xml
new file mode 100644
index 0000000..d718b1d
--- /dev/null
+++ b/opengl/tests/gl2_java/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+ them to be changed based on the locale and options. -->
+
+<resources>
+ <!-- Simple strings. -->
+ <string name="gl2java_activity">GL2Java</string>
+
+</resources>
+
diff --git a/opengl/tests/gl2_java/src/com/android/gl2java/GL2JavaActivity.java b/opengl/tests/gl2_java/src/com/android/gl2java/GL2JavaActivity.java
new file mode 100644
index 0000000..37654fb
--- /dev/null
+++ b/opengl/tests/gl2_java/src/com/android/gl2java/GL2JavaActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+package com.android.gl2java;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GL2JavaActivity extends Activity {
+
+ GL2JavaView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new GL2JavaView(getApplication());
+ setContentView(mView);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/opengl/tests/gl2_java/src/com/android/gl2java/GL2JavaView.java b/opengl/tests/gl2_java/src/com/android/gl2java/GL2JavaView.java
new file mode 100644
index 0000000..7f2bfd3
--- /dev/null
+++ b/opengl/tests/gl2_java/src/com/android/gl2java/GL2JavaView.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package com.android.gl2java;
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation. This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class GL2JavaView extends GLSurfaceView {
+ private static String TAG = "GL2JavaView";
+
+ public GL2JavaView(Context context) {
+ super(context);
+ setEGLContextClientVersion(2);
+ setRenderer(new Renderer());
+ }
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+
+ public Renderer() {
+ mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4)
+ .order(ByteOrder.nativeOrder()).asFloatBuffer();
+ mTriangleVertices.put(mTriangleVerticesData).position(0);
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+ GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+ GLES20.glUseProgram(mProgram);
+ checkGlError("glUseProgram");
+
+ GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 0, mTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ GLES20.glEnableVertexAttribArray(mvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GLES20.glViewport(0, 0, width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ mProgram = createProgram(mVertexShader, mFragmentShader);
+ if (mProgram == 0) {
+ return;
+ }
+ mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+ checkGlError("glGetAttribLocation");
+ if (mvPositionHandle == -1) {
+ throw new RuntimeException("Could not get attrib location for vPosition");
+ }
+ }
+
+ private int loadShader(int shaderType, String source) {
+ int shader = GLES20.glCreateShader(shaderType);
+ if (shader != 0) {
+ GLES20.glShaderSource(shader, source);
+ GLES20.glCompileShader(shader);
+ int[] compiled = new int[1];
+ GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
+ if (compiled[0] == 0) {
+ Log.e(TAG, "Could not compile shader " + shaderType + ":");
+ Log.e(TAG, GLES20.glGetShaderInfoLog(shader));
+ GLES20.glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ return shader;
+ }
+
+ private int createProgram(String vertexSource, String fragmentSource) {
+ int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
+ if (vertexShader == 0) {
+ return 0;
+ }
+
+ int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
+ if (pixelShader == 0) {
+ return 0;
+ }
+
+ int program = GLES20.glCreateProgram();
+ if (program != 0) {
+ GLES20.glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ GLES20.glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ GLES20.glLinkProgram(program);
+ int[] linkStatus = new int[1];
+ GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
+ if (linkStatus[0] != GLES20.GL_TRUE) {
+ Log.e(TAG, "Could not link program: ");
+ Log.e(TAG, GLES20.glGetProgramInfoLog(program));
+ GLES20.glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+ }
+
+ private void checkGlError(String op) {
+ int error;
+ while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+ Log.e(TAG, op + ": glError " + error);
+ throw new RuntimeException(op + ": glError " + error);
+ }
+ }
+
+ private final float[] mTriangleVerticesData = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+
+ private FloatBuffer mTriangleVertices;
+
+ private final String mVertexShader = "attribute vec4 vPosition;\n"
+ + "void main() {\n"
+ + " gl_Position = vPosition;\n"
+ + "}\n";
+
+ private final String mFragmentShader = "precision mediump float;\n"
+ + "void main() {\n"
+ + " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ + "}\n";
+
+ private int mProgram;
+ private int mvPositionHandle;
+
+ }
+}
+
diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen
index 9bff0b2..6c1a231 100755
--- a/opengl/tools/glgen/gen
+++ b/opengl/tools/glgen/gen
@@ -63,7 +63,7 @@
pushd out > /dev/null
mkdir classes
-javac -d classes com/google/android/gles_jni/GLImpl.java javax/microedition/khronos/opengles/GL10.java javax/microedition/khronos/opengles/GL10Ext.java javax/microedition/khronos/opengles/GL11.java javax/microedition/khronos/opengles/GL11Ext.java javax/microedition/khronos/opengles/GL11ExtensionPack.java android/opengl/GLES10.java android/opengl/GLES10Ext.java android/opengl/GLES11.java android/opengl/GLES11Ext.java
+javac -d classes com/google/android/gles_jni/GLImpl.java javax/microedition/khronos/opengles/GL10.java javax/microedition/khronos/opengles/GL10Ext.java javax/microedition/khronos/opengles/GL11.java javax/microedition/khronos/opengles/GL11Ext.java javax/microedition/khronos/opengles/GL11ExtensionPack.java android/opengl/GLES10.java android/opengl/GLES10Ext.java android/opengl/GLES11.java android/opengl/GLES11Ext.java android/opengl/GLES20.java
popd > /dev/null
JAVA_RESULT=$?
if [ $JAVA_RESULT -ne 0 ]; then
@@ -109,7 +109,7 @@
compareGenerated ../../java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x
done
-for x in GLES10 GLES10Ext GLES11 GLES11Ext
+for x in GLES10 GLES10Ext GLES11 GLES11Ext GLES20
do
compareGenerated ../../java/android/opengl generated/android/opengl ${x}.java
compareGenerated ../../../core/jni generated/C android_opengl_${x}.cpp
diff --git a/opengl/tools/glgen/specs/gles11/GLES20.spec b/opengl/tools/glgen/specs/gles11/GLES20.spec
new file mode 100644
index 0000000..61094d1
--- /dev/null
+++ b/opengl/tools/glgen/specs/gles11/GLES20.spec
@@ -0,0 +1,142 @@
+void glActiveTexture ( GLenum texture )
+void glAttachShader ( GLuint program, GLuint shader )
+void glBindAttribLocation ( GLuint program, GLuint index, const char *name )
+void glBindBuffer ( GLenum target, GLuint buffer )
+void glBindFramebuffer ( GLenum target, GLuint framebuffer )
+void glBindRenderbuffer ( GLenum target, GLuint renderbuffer )
+void glBindTexture ( GLenum target, GLuint texture )
+void glBlendColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
+void glBlendEquation ( GLenum mode )
+void glBlendEquationSeparate ( GLenum modeRGB, GLenum modeAlpha )
+void glBlendFunc ( GLenum sfactor, GLenum dfactor )
+void glBlendFuncSeparate ( GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha )
+void glBufferData ( GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage )
+void glBufferSubData ( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data )
+GLenum glCheckFramebufferStatus ( GLenum target )
+void glClear ( GLbitfield mask )
+void glClearColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
+void glClearDepthf ( GLclampf depth )
+void glClearStencil ( GLint s )
+void glColorMask ( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha )
+void glCompileShader ( GLuint shader )
+void glCompressedTexImage2D ( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data )
+void glCompressedTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data )
+void glCopyTexImage2D ( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
+void glCopyTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height )
+GLuint glCreateProgram ( void )
+GLuint glCreateShader ( GLenum type )
+void glCullFace ( GLenum mode )
+void glDeleteBuffers ( GLsizei n, const GLuint *buffers )
+void glDeleteFramebuffers ( GLsizei n, const GLuint *framebuffers )
+void glDeleteProgram ( GLuint program )
+void glDeleteRenderbuffers ( GLsizei n, const GLuint *renderbuffers )
+void glDeleteShader ( GLuint shader )
+void glDeleteTextures ( GLsizei n, const GLuint *textures )
+void glDepthFunc ( GLenum func )
+void glDepthMask ( GLboolean flag )
+void glDepthRangef ( GLclampf zNear, GLclampf zFar )
+void glDetachShader ( GLuint program, GLuint shader )
+void glDisable ( GLenum cap )
+void glDisableVertexAttribArray ( GLuint index )
+void glDrawArrays ( GLenum mode, GLint first, GLsizei count )
+void glDrawElements ( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
+void glEnable ( GLenum cap )
+void glEnableVertexAttribArray ( GLuint index )
+void glFinish ( void )
+void glFlush ( void )
+void glFramebufferRenderbuffer ( GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer )
+void glFramebufferTexture2D ( GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level )
+void glFrontFace ( GLenum mode )
+void glGenBuffers ( GLsizei n, GLuint *buffers )
+void glGenerateMipmap ( GLenum target )
+void glGenFramebuffers ( GLsizei n, GLuint *framebuffers )
+void glGenRenderbuffers ( GLsizei n, GLuint *renderbuffers )
+void glGenTextures ( GLsizei n, GLuint *textures )
+void glGetActiveAttrib ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name )
+void glGetActiveUniform ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name )
+void glGetAttachedShaders ( GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders )
+int glGetAttribLocation ( GLuint program, const char *name )
+void glGetBooleanv ( GLenum pname, GLboolean *params )
+void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params )
+GLenum glGetError ( void )
+void glGetFloatv ( GLenum pname, GLfloat *params )
+void glGetFramebufferAttachmentParameteriv ( GLenum target, GLenum attachment, GLenum pname, GLint *params )
+void glGetIntegerv ( GLenum pname, GLint *params )
+void glGetProgramiv ( GLuint program, GLenum pname, GLint *params )
+void glGetProgramInfoLog ( GLuint program, GLsizei bufsize, GLsizei *length, char *infolog )
+void glGetRenderbufferParameteriv ( GLenum target, GLenum pname, GLint *params )
+void glGetShaderiv ( GLuint shader, GLenum pname, GLint *params )
+void glGetShaderInfoLog ( GLuint shader, GLsizei bufsize, GLsizei *length, char *infolog )
+void glGetShaderPrecisionFormat ( GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision )
+void glGetShaderSource ( GLuint shader, GLsizei bufsize, GLsizei *length, char *source )
+const GLubyte * glGetString ( GLenum name )
+void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params )
+void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params )
+void glGetUniformfv ( GLuint program, GLint location, GLfloat *params )
+void glGetUniformiv ( GLuint program, GLint location, GLint *params )
+int glGetUniformLocation ( GLuint program, const char *name )
+void glGetVertexAttribfv ( GLuint index, GLenum pname, GLfloat *params )
+void glGetVertexAttribiv ( GLuint index, GLenum pname, GLint *params )
+// void glGetVertexAttribPointerv ( GLuint index, GLenum pname, void **pointer )
+void glHint ( GLenum target, GLenum mode )
+GLboolean glIsBuffer ( GLuint buffer )
+GLboolean glIsEnabled ( GLenum cap )
+GLboolean glIsFramebuffer ( GLuint framebuffer )
+GLboolean glIsProgram ( GLuint program )
+GLboolean glIsRenderbuffer ( GLuint renderbuffer )
+GLboolean glIsShader ( GLuint shader )
+GLboolean glIsTexture ( GLuint texture )
+void glLineWidth ( GLfloat width )
+void glLinkProgram ( GLuint program )
+void glPixelStorei ( GLenum pname, GLint param )
+void glPolygonOffset ( GLfloat factor, GLfloat units )
+void glReadPixels ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels )
+void glReleaseShaderCompiler ( void )
+void glRenderbufferStorage ( GLenum target, GLenum internalformat, GLsizei width, GLsizei height )
+void glSampleCoverage ( GLclampf value, GLboolean invert )
+void glScissor ( GLint x, GLint y, GLsizei width, GLsizei height )
+void glShaderBinary ( GLsizei n, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length )
+void glShaderSource ( GLuint shader )
+void glStencilFunc ( GLenum func, GLint ref, GLuint mask )
+void glStencilFuncSeparate ( GLenum face, GLenum func, GLint ref, GLuint mask )
+void glStencilMask ( GLuint mask )
+void glStencilMaskSeparate ( GLenum face, GLuint mask )
+void glStencilOp ( GLenum fail, GLenum zfail, GLenum zpass )
+void glStencilOpSeparate ( GLenum face, GLenum fail, GLenum zfail, GLenum zpass )
+void glTexImage2D ( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+void glTexParameterf ( GLenum target, GLenum pname, GLfloat param )
+void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params )
+void glTexParameteri ( GLenum target, GLenum pname, GLint param )
+void glTexParameteriv ( GLenum target, GLenum pname, const GLint *params )
+void glTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+void glUniform1f ( GLint location, GLfloat x )
+void glUniform1fv ( GLint location, GLsizei count, const GLfloat *v )
+void glUniform1i ( GLint location, GLint x )
+void glUniform1iv ( GLint location, GLsizei count, const GLint *v )
+void glUniform2f ( GLint location, GLfloat x, GLfloat y )
+void glUniform2fv ( GLint location, GLsizei count, const GLfloat *v )
+void glUniform2i ( GLint location, GLint x, GLint y )
+void glUniform2iv ( GLint location, GLsizei count, const GLint *v )
+void glUniform3f ( GLint location, GLfloat x, GLfloat y, GLfloat z )
+void glUniform3fv ( GLint location, GLsizei count, const GLfloat *v )
+void glUniform3i ( GLint location, GLint x, GLint y, GLint z )
+void glUniform3iv ( GLint location, GLsizei count, const GLint *v )
+void glUniform4f ( GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+void glUniform4fv ( GLint location, GLsizei count, const GLfloat *v )
+void glUniform4i ( GLint location, GLint x, GLint y, GLint z, GLint w )
+void glUniform4iv ( GLint location, GLsizei count, const GLint *v )
+void glUniformMatrix2fv ( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value )
+void glUniformMatrix3fv ( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value )
+void glUniformMatrix4fv ( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value )
+void glUseProgram ( GLuint program )
+void glValidateProgram ( GLuint program )
+void glVertexAttrib1f ( GLuint indx, GLfloat x )
+void glVertexAttrib1fv ( GLuint indx, const GLfloat *values )
+void glVertexAttrib2f ( GLuint indx, GLfloat x, GLfloat y )
+void glVertexAttrib2fv ( GLuint indx, const GLfloat *values )
+void glVertexAttrib3f ( GLuint indx, GLfloat x, GLfloat y, GLfloat z )
+void glVertexAttrib3fv ( GLuint indx, const GLfloat *values )
+void glVertexAttrib4f ( GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
+void glVertexAttrib4fv ( GLuint indx, const GLfloat *values )
+void glVertexAttribPointer ( GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr )
+void glViewport ( GLint x, GLint y, GLsizei width, GLsizei height )
\ No newline at end of file
diff --git a/opengl/tools/glgen/specs/gles11/checks.spec b/opengl/tools/glgen/specs/gles11/checks.spec
index 1468ab9..f917128 100644
--- a/opengl/tools/glgen/specs/gles11/checks.spec
+++ b/opengl/tools/glgen/specs/gles11/checks.spec
@@ -37,7 +37,6 @@
glBlendEquationSeparate unsupported
glBlendFuncSeparate unsupported
glCheckFramebufferStatusOES unsupported return 0
-glCurrentPaletteMatrixOES unsupported
glDeleteFramebuffersOES unsupported
glDeleteRenderbuffersOES unsupported
glFramebufferRenderbufferOES unsupported
@@ -52,11 +51,8 @@
glGetTexGen unsupported
glIsFramebufferOES unsupported return JNI_FALSE
glIsRenderbufferOES unsupported return JNI_FALSE
-glLoadPaletteFromModelViewMatrixOES unsupported
-glMatrixIndexPointerOES unsupported
glRenderbufferStorageOES unsupported return false
glTexGen unsupported
glTexGenf unsupported
glTexGeni unsupported
glTexGenx unsupported
-glWeightPointerOES unsupported
diff --git a/opengl/tools/glgen/specs/jsr239/glspec-checks b/opengl/tools/glgen/specs/jsr239/glspec-checks
index 063cdc7..c28e403 100644
--- a/opengl/tools/glgen/specs/jsr239/glspec-checks
+++ b/opengl/tools/glgen/specs/jsr239/glspec-checks
@@ -35,7 +35,6 @@
glBlendEquationSeparate unsupported
glBlendFuncSeparate unsupported
glCheckFramebufferStatusOES unsupported return 0
-glCurrentPaletteMatrixOES unsupported
glDeleteFramebuffersOES unsupported
glDeleteRenderbuffersOES unsupported
glFramebufferRenderbufferOES unsupported
@@ -50,11 +49,8 @@
glGetTexGen unsupported
glIsFramebufferOES unsupported return JNI_FALSE
glIsRenderbufferOES unsupported return JNI_FALSE
-glLoadPaletteFromModelViewMatrixOES unsupported
-glMatrixIndexPointerOES unsupported
glRenderbufferStorageOES unsupported return false
glTexGen unsupported
glTexGenf unsupported
glTexGeni unsupported
glTexGenx unsupported
-glWeightPointerOES unsupported
diff --git a/opengl/tools/glgen/src/CType.java b/opengl/tools/glgen/src/CType.java
index 826c90d..d49e9ef 100644
--- a/opengl/tools/glgen/src/CType.java
+++ b/opengl/tools/glgen/src/CType.java
@@ -44,8 +44,12 @@
baseType.equals("void");
}
+ public boolean isConstCharPointer() {
+ return isConst && isPointer && baseType.equals("char");
+ }
+
public boolean isTypedPointer() {
- return isPointer() && !isVoid();
+ return isPointer() && !isVoid() && !isConstCharPointer();
}
public void setBaseType(String baseType) {
diff --git a/opengl/tools/glgen/src/GenerateGLES.java b/opengl/tools/glgen/src/GenerateGLES.java
index 60775b7..08063f3 100644
--- a/opengl/tools/glgen/src/GenerateGLES.java
+++ b/opengl/tools/glgen/src/GenerateGLES.java
@@ -70,7 +70,7 @@
// Generate files
for(String suffix: new String[] {"GLES10", "GLES10Ext",
- "GLES11", "GLES11Ext"})
+ "GLES11", "GLES11Ext", "GLES20"})
{
BufferedReader spec11Reader =
new BufferedReader(new FileReader("specs/gles11/"
diff --git a/opengl/tools/glgen/src/JType.java b/opengl/tools/glgen/src/JType.java
index df1177b..32d9fe7 100644
--- a/opengl/tools/glgen/src/JType.java
+++ b/opengl/tools/glgen/src/JType.java
@@ -6,6 +6,7 @@
String baseType;
boolean isArray;
boolean isClass;
+ boolean isString;
static HashMap<CType,JType> typeMapping = new HashMap<CType,JType>();
static HashMap<CType,JType> arrayTypeMapping = new HashMap<CType,JType>();
@@ -27,7 +28,10 @@
typeMapping.put(new CType("GLubyte"), new JType("byte"));
typeMapping.put(new CType("GLuint"), new JType("int"));
typeMapping.put(new CType("void"), new JType("void"));
- typeMapping.put(new CType("GLubyte", true, true), new JType("String"));
+ typeMapping.put(new CType("GLubyte", true, true), new JType("String", false, false));
+ typeMapping.put(new CType("char", false, true), new JType("byte"));
+ typeMapping.put(new CType("char", true, true), new JType("String", false, false));
+ typeMapping.put(new CType("int"), new JType("int"));
// Untyped pointers map to untyped Buffers
typeMapping.put(new CType("GLvoid", true, true),
@@ -42,6 +46,8 @@
// Typed pointers map to typed Buffers
typeMapping.put(new CType("GLboolean", false, true),
new JType("java.nio.IntBuffer", true, false));
+ typeMapping.put(new CType("GLenum", false, true),
+ new JType("java.nio.IntBuffer", true, false));
typeMapping.put(new CType("GLfixed", false, true),
new JType("java.nio.IntBuffer", true, false));
typeMapping.put(new CType("GLfixed", true, true),
@@ -54,6 +60,8 @@
new JType("java.nio.IntBuffer", true, false));
typeMapping.put(new CType("GLint", true, true),
new JType("java.nio.IntBuffer", true, false));
+ typeMapping.put(new CType("GLsizei", false, true),
+ new JType("java.nio.IntBuffer", true, false));
typeMapping.put(new CType("GLuint", false, true),
new JType("java.nio.IntBuffer", true, false));
typeMapping.put(new CType("GLuint", true, true),
@@ -62,8 +70,11 @@
new JType("java.nio.ShortBuffer", true, false));
// Typed pointers map to arrays + offsets
+ arrayTypeMapping.put(new CType("char", false, true),
+ new JType("byte", false, true));
arrayTypeMapping.put(new CType("GLboolean", false, true),
new JType("boolean", false, true));
+ arrayTypeMapping.put(new CType("GLenum", false, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfixed", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfixed", false, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfloat", false, true), new JType("float", false, true));
@@ -71,6 +82,8 @@
arrayTypeMapping.put(new CType("GLint", false, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLint", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLshort", true, true), new JType("short", false, true));
+ arrayTypeMapping.put(new CType("GLsizei", false, true), new JType("int", false, true));
+ arrayTypeMapping.put(new CType("GLsizei", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLuint", false, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLuint", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLintptr"), new JType("int", false, true));
@@ -109,6 +122,10 @@
return isClass;
}
+ public boolean isString() {
+ return baseType.equals("String");
+ }
+
public boolean isPrimitive() {
return !isClass() && !isArray();
}
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index 2cdb244..e79170a 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -37,6 +37,12 @@
jniName += "L";
} else if (baseType.equals("byte")) {
jniName += "B";
+ } else if (baseType.equals("String")) {
+ jniName += "Ljava/lang/String;";
+ } else if (baseType.equals("void")) {
+ // nothing.
+ } else {
+ throw new RuntimeException("Uknown primitive basetype " + baseType);
}
return jniName;
}
@@ -113,10 +119,15 @@
emitFunction(jfunc, out, false, false);
}
+ boolean isPointerFunc(JFunc jfunc) {
+ String name = jfunc.getName();
+ return (name.endsWith("Pointer") || name.endsWith("PointerOES"))
+ && jfunc.getCFunc().hasPointerArg();
+ }
+
void emitFunctionCall(JFunc jfunc, PrintStream out, String iii, boolean grabArray) {
boolean isVoid = jfunc.getType().isVoid();
- boolean isPointerFunc = jfunc.getName().endsWith("Pointer") &&
- jfunc.getCFunc().hasPointerArg();
+ boolean isPointerFunc = isPointerFunc(jfunc);
if (!isVoid) {
out.println(iii +
@@ -400,9 +411,7 @@
* if !interfaceDecl: public <returntype> func(args) { body }
*/
void emitFunction(JFunc jfunc, PrintStream out, boolean nativeDecl, boolean interfaceDecl) {
- boolean isPointerFunc =
- jfunc.getName().endsWith("Pointer") &&
- jfunc.getCFunc().hasPointerArg();
+ boolean isPointerFunc = isPointerFunc(jfunc);
if (!nativeDecl && !interfaceDecl && !isPointerFunc) {
// If it's not a pointer function, we've already emitted it
@@ -504,6 +513,34 @@
out.println(iii + " (stride >= 0)) {");
out.println(iii + indent + "_vertexPointer = pointer;");
out.println(iii + "}");
+ } else if (fname.equals("glPointSizePointerOES")) {
+ out.println(iii + "if (((type == GL_FLOAT) ||");
+ out.println(iii + " (type == GL_FIXED)) &&");
+ out.println(iii + " (stride >= 0)) {");
+ out.println(iii + indent + "_pointSizePointerOES = pointer;");
+ out.println(iii + "}");
+ } else if (fname.equals("glMatrixIndexPointerOES")) {
+ out.println(iii + "if (((size == 2) ||");
+ out.println(iii + " (size == 3) ||");
+ out.println(iii + " (size == 4)) &&");
+ out.println(iii + " ((type == GL_FLOAT) ||");
+ out.println(iii + " (type == GL_BYTE) ||");
+ out.println(iii + " (type == GL_SHORT) ||");
+ out.println(iii + " (type == GL_FIXED)) &&");
+ out.println(iii + " (stride >= 0)) {");
+ out.println(iii + indent + "_matrixIndexPointerOES = pointer;");
+ out.println(iii + "}");
+ } else if (fname.equals("glWeightPointer")) {
+ out.println(iii + "if (((size == 2) ||");
+ out.println(iii + " (size == 3) ||");
+ out.println(iii + " (size == 4)) &&");
+ out.println(iii + " ((type == GL_FLOAT) ||");
+ out.println(iii + " (type == GL_BYTE) ||");
+ out.println(iii + " (type == GL_SHORT) ||");
+ out.println(iii + " (type == GL_FIXED)) &&");
+ out.println(iii + " (stride >= 0)) {");
+ out.println(iii + indent + "_weightPointerOES = pointer;");
+ out.println(iii + "}");
}
}
@@ -603,9 +640,9 @@
//
String outName = "android_" + jfunc.getName();
- boolean isPointerFunc = outName.endsWith("Pointer") &&
- jfunc.getCFunc().hasPointerArg();
+ boolean isPointerFunc = isPointerFunc(jfunc);
boolean isVBOPointerFunc = (outName.endsWith("Pointer") ||
+ outName.endsWith("PointerOES") ||
outName.endsWith("DrawElements")) &&
!jfunc.getCFunc().hasPointerArg();
if (isPointerFunc) {
@@ -629,7 +666,7 @@
}
// Append signature to function name
- String sig = getJniMangledName(signature).replace('.', '_');
+ String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_');
out.print("__" + sig);
outName += "__" + sig;
@@ -652,6 +689,7 @@
nativeRegistrations.add(s);
List<Integer> nonPrimitiveArgs = new ArrayList<Integer>();
+ List<Integer> stringArgs = new ArrayList<Integer>();
int numBufferArgs = 0;
List<String> bufferArgNames = new ArrayList<String>();
@@ -682,6 +720,9 @@
} else {
suffix = "";
}
+ if (argType.isString()) {
+ stringArgs.add(new Integer(i));
+ }
out.print(getJniType(argType) + " " + jfunc.getArgName(i) + suffix);
}
@@ -692,14 +733,19 @@
int numArrays = 0;
int numBuffers = 0;
+ int numStrings = 0;
for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
int idx = nonPrimitiveArgs.get(i).intValue();
- if (jfunc.getArgType(idx).isArray()) {
+ JType argType = jfunc.getArgType(idx);
+ if (argType.isArray()) {
++numArrays;
}
- if (jfunc.getArgType(idx).isBuffer()) {
+ if (argType.isBuffer()) {
++numBuffers;
}
+ if (argType.isString()) {
+ ++numStrings;
+ }
}
// Emit method body
@@ -736,7 +782,9 @@
"android::gl::ogles_context_t *ctx = getContext(_env, _this);");
}
- boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0) &&
+ boolean initializeReturnValue = stringArgs.size() > 0;
+
+ boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) &&
hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs);
// mChecker.getChecks(cfunc.getName()) != null
@@ -759,6 +807,9 @@
if (retval != null) {
out.println(indent + returnType.getDeclaration() +
" _returnValue = " + retval + ";");
+ } else if (initializeReturnValue) {
+ out.println(indent + returnType.getDeclaration() +
+ " _returnValue = 0;");
} else {
out.println(indent + returnType.getDeclaration() +
" _returnValue;");
@@ -789,7 +840,7 @@
jfunc.getArgName(idx) +
"_base = (" + decl + ") 0;");
}
- remaining = (numArrays <= 1 && numBuffers <= 1) ? "_remaining" :
+ remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
"_" + cname + "Remaining";
out.println(indent +
"jint " + remaining + ";");
@@ -803,6 +854,40 @@
out.println();
}
+ // Emit local variable declaration for strings
+ if (stringArgs.size() > 0) {
+ for (int i = 0; i < stringArgs.size(); i++) {
+ int idx = stringArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ out.println(indent + "const char* _native" + cname + " = 0;");
+ }
+
+ out.println();
+ }
+
+ // Null pointer checks and GetStringUTFChars
+ if (stringArgs.size() > 0) {
+ for (int i = 0; i < stringArgs.size(); i++) {
+ int idx = stringArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
+ String decl = type.getDeclaration();
+ out.println(indent + "if (!" + cname + ") {");
+ out.println(indent + " _env->ThrowNew(IAEClass, \"" + cname + " == null\");");
+ out.println(indent + " goto exit;");
+ needsExit = true;
+ out.println(indent + "}");
+
+ out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);");
+ }
+
+ out.println();
+ }
+
// Emit 'GetPrimitiveArrayCritical' for arrays
// Emit 'GetPointer' calls for Buffer pointers
int bufArgIdx = 0;
@@ -814,7 +899,7 @@
String cname = cfunc.getArgName(cIndex);
offset = numArrays <= 1 ? "offset" :
cname + "Offset";
- remaining = (numArrays <= 1 && numBuffers <= 1) ? "_remaining" :
+ remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
"_" + cname + "Remaining";
if (jfunc.getArgType(idx).isArray()) {
@@ -957,8 +1042,11 @@
out.print(indent + indent +
"(" +
typecast +
- ")" +
- cfunc.getArgName(i));
+ ")");
+ if (cfunc.getArgType(i).isConstCharPointer()) {
+ out.print("_native");
+ }
+ out.print(cfunc.getArgName(i));
if (i == numArgs - 1) {
if (isPointerFunc) {
@@ -1025,6 +1113,22 @@
}
}
+ // Emit local variable declaration for strings
+ if (stringArgs.size() > 0) {
+ for (int i = 0; i < stringArgs.size(); i++) {
+ int idx = stringArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ out.println(indent + "if (_native" + cname + ") {");
+ out.println(indent + " _env->ReleaseStringUTFChars(" + cname + ", _native" + cname + ");");
+ out.println(indent + "}");
+ }
+
+ out.println();
+ }
+
+
if (!isVoid) {
out.println(indent + "return _returnValue;");
}
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if b/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if
index 428ccee..c5e34cd 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if
+++ b/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if
@@ -18,6 +18,8 @@
package android.opengl;
+import java.nio.Buffer;
+
public class GLES11Ext {
public static final int GL_BLEND_EQUATION_RGB_OES = 0x8009;
public static final int GL_BLEND_EQUATION_ALPHA_OES = 0x883D;
@@ -127,4 +129,10 @@
static {
_nativeClassInit();
}
-
\ No newline at end of file
+
+ private static final int GL_BYTE = GLES10.GL_BYTE;
+ private static final int GL_FIXED = GLES10.GL_FIXED;
+ private static final int GL_FLOAT = GLES10.GL_FLOAT;
+ private static final int GL_SHORT = GLES10.GL_SHORT;
+
+ private static Buffer _matrixIndexPointerOES;
\ No newline at end of file
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp
index 294d1ce..2548b32 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp
@@ -23,6 +23,15 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
+/* special calls implemented in Android's GLES wrapper used to more
+ * efficiently bound-check passed arrays */
+extern "C" {
+GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr, GLsizei count);
+GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type, GLsizei stride,
+ const GLvoid *ptr, GLsizei count);
+}
+
static int initialized = 0;
static jclass nioAccessClass;
@@ -121,5 +130,17 @@
commit ? 0 : JNI_ABORT);
}
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
// --------------------------------------------------------------------------
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11Header.java-if b/opengl/tools/glgen/stubs/gles11/GLES11Header.java-if
index 26f466f..81572d2 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11Header.java-if
+++ b/opengl/tools/glgen/stubs/gles11/GLES11Header.java-if
@@ -149,3 +149,4 @@
_nativeClassInit();
}
+ private static Buffer _pointSizePointerOES;
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp
index 294d1ce..4c297f7 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp
+++ b/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp
@@ -23,6 +23,13 @@
#include <GLES/gl.h>
#include <GLES/glext.h>
+/* special calls implemented in Android's GLES wrapper used to more
+ * efficiently bound-check passed arrays */
+extern "C" {
+GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type, GLsizei stride,
+ const GLvoid *ptr, GLsizei count);
+}
+
static int initialized = 0;
static jclass nioAccessClass;
@@ -121,5 +128,18 @@
commit ? 0 : JNI_ABORT);
}
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
+
// --------------------------------------------------------------------------
diff --git a/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if b/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if
new file mode 100644
index 0000000..b615e0a
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/GLES20Header.java-if
@@ -0,0 +1,330 @@
+**
+** 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.
+*/
+
+// This source file is automatically generated
+
+package android.opengl;
+
+/** OpenGL ES 2.0
+ */
+public class GLES20 {
+ public static final int GL_ACTIVE_TEXTURE = 0x84E0;
+ public static final int GL_DEPTH_BUFFER_BIT = 0x00000100;
+ public static final int GL_STENCIL_BUFFER_BIT = 0x00000400;
+ public static final int GL_COLOR_BUFFER_BIT = 0x00004000;
+ public static final int GL_FALSE = 0;
+ public static final int GL_TRUE = 1;
+ public static final int GL_POINTS = 0x0000;
+ public static final int GL_LINES = 0x0001;
+ public static final int GL_LINE_LOOP = 0x0002;
+ public static final int GL_LINE_STRIP = 0x0003;
+ public static final int GL_TRIANGLES = 0x0004;
+ public static final int GL_TRIANGLE_STRIP = 0x0005;
+ public static final int GL_TRIANGLE_FAN = 0x0006;
+ public static final int GL_ZERO = 0;
+ public static final int GL_ONE = 1;
+ public static final int GL_SRC_COLOR = 0x0300;
+ public static final int GL_ONE_MINUS_SRC_COLOR = 0x0301;
+ public static final int GL_SRC_ALPHA = 0x0302;
+ public static final int GL_ONE_MINUS_SRC_ALPHA = 0x0303;
+ public static final int GL_DST_ALPHA = 0x0304;
+ public static final int GL_ONE_MINUS_DST_ALPHA = 0x0305;
+ public static final int GL_DST_COLOR = 0x0306;
+ public static final int GL_ONE_MINUS_DST_COLOR = 0x0307;
+ public static final int GL_SRC_ALPHA_SATURATE = 0x0308;
+ public static final int GL_FUNC_ADD = 0x8006;
+ public static final int GL_BLEND_EQUATION = 0x8009;
+ public static final int GL_BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ public static final int GL_BLEND_EQUATION_ALPHA = 0x883D;
+ public static final int GL_FUNC_SUBTRACT = 0x800A;
+ public static final int GL_FUNC_REVERSE_SUBTRACT = 0x800B;
+ public static final int GL_BLEND_DST_RGB = 0x80C8;
+ public static final int GL_BLEND_SRC_RGB = 0x80C9;
+ public static final int GL_BLEND_DST_ALPHA = 0x80CA;
+ public static final int GL_BLEND_SRC_ALPHA = 0x80CB;
+ public static final int GL_CONSTANT_COLOR = 0x8001;
+ public static final int GL_ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ public static final int GL_CONSTANT_ALPHA = 0x8003;
+ public static final int GL_ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ public static final int GL_BLEND_COLOR = 0x8005;
+ public static final int GL_ARRAY_BUFFER = 0x8892;
+ public static final int GL_ELEMENT_ARRAY_BUFFER = 0x8893;
+ public static final int GL_ARRAY_BUFFER_BINDING = 0x8894;
+ public static final int GL_ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+ public static final int GL_STREAM_DRAW = 0x88E0;
+ public static final int GL_STATIC_DRAW = 0x88E4;
+ public static final int GL_DYNAMIC_DRAW = 0x88E8;
+ public static final int GL_BUFFER_SIZE = 0x8764;
+ public static final int GL_BUFFER_USAGE = 0x8765;
+ public static final int GL_CURRENT_VERTEX_ATTRIB = 0x8626;
+ public static final int GL_FRONT = 0x0404;
+ public static final int GL_BACK = 0x0405;
+ public static final int GL_FRONT_AND_BACK = 0x0408;
+ public static final int GL_TEXTURE_2D = 0x0DE1;
+ public static final int GL_CULL_FACE = 0x0B44;
+ public static final int GL_BLEND = 0x0BE2;
+ public static final int GL_DITHER = 0x0BD0;
+ public static final int GL_STENCIL_TEST = 0x0B90;
+ public static final int GL_DEPTH_TEST = 0x0B71;
+ public static final int GL_SCISSOR_TEST = 0x0C11;
+ public static final int GL_POLYGON_OFFSET_FILL = 0x8037;
+ public static final int GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ public static final int GL_SAMPLE_COVERAGE = 0x80A0;
+ public static final int GL_NO_ERROR = 0;
+ public static final int GL_INVALID_ENUM = 0x0500;
+ public static final int GL_INVALID_VALUE = 0x0501;
+ public static final int GL_INVALID_OPERATION = 0x0502;
+ public static final int GL_OUT_OF_MEMORY = 0x0505;
+ public static final int GL_CW = 0x0900;
+ public static final int GL_CCW = 0x0901;
+ public static final int GL_LINE_WIDTH = 0x0B21;
+ public static final int GL_ALIASED_POINT_SIZE_RANGE = 0x846D;
+ public static final int GL_ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ public static final int GL_CULL_FACE_MODE = 0x0B45;
+ public static final int GL_FRONT_FACE = 0x0B46;
+ public static final int GL_DEPTH_RANGE = 0x0B70;
+ public static final int GL_DEPTH_WRITEMASK = 0x0B72;
+ public static final int GL_DEPTH_CLEAR_VALUE = 0x0B73;
+ public static final int GL_DEPTH_FUNC = 0x0B74;
+ public static final int GL_STENCIL_CLEAR_VALUE = 0x0B91;
+ public static final int GL_STENCIL_FUNC = 0x0B92;
+ public static final int GL_STENCIL_FAIL = 0x0B94;
+ public static final int GL_STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ public static final int GL_STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ public static final int GL_STENCIL_REF = 0x0B97;
+ public static final int GL_STENCIL_VALUE_MASK = 0x0B93;
+ public static final int GL_STENCIL_WRITEMASK = 0x0B98;
+ public static final int GL_STENCIL_BACK_FUNC = 0x8800;
+ public static final int GL_STENCIL_BACK_FAIL = 0x8801;
+ public static final int GL_STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ public static final int GL_STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ public static final int GL_STENCIL_BACK_REF = 0x8CA3;
+ public static final int GL_STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ public static final int GL_STENCIL_BACK_WRITEMASK = 0x8CA5;
+ public static final int GL_VIEWPORT = 0x0BA2;
+ public static final int GL_SCISSOR_BOX = 0x0C10;
+ public static final int GL_COLOR_CLEAR_VALUE = 0x0C22;
+ public static final int GL_COLOR_WRITEMASK = 0x0C23;
+ public static final int GL_UNPACK_ALIGNMENT = 0x0CF5;
+ public static final int GL_PACK_ALIGNMENT = 0x0D05;
+ public static final int GL_MAX_TEXTURE_SIZE = 0x0D33;
+ public static final int GL_MAX_VIEWPORT_DIMS = 0x0D3A;
+ public static final int GL_SUBPIXEL_BITS = 0x0D50;
+ public static final int GL_RED_BITS = 0x0D52;
+ public static final int GL_GREEN_BITS = 0x0D53;
+ public static final int GL_BLUE_BITS = 0x0D54;
+ public static final int GL_ALPHA_BITS = 0x0D55;
+ public static final int GL_DEPTH_BITS = 0x0D56;
+ public static final int GL_STENCIL_BITS = 0x0D57;
+ public static final int GL_POLYGON_OFFSET_UNITS = 0x2A00;
+ public static final int GL_POLYGON_OFFSET_FACTOR = 0x8038;
+ public static final int GL_TEXTURE_BINDING_2D = 0x8069;
+ public static final int GL_SAMPLE_BUFFERS = 0x80A8;
+ public static final int GL_SAMPLES = 0x80A9;
+ public static final int GL_SAMPLE_COVERAGE_VALUE = 0x80AA;
+ public static final int GL_SAMPLE_COVERAGE_INVERT = 0x80AB;
+ public static final int GL_NUM_COMPRESSED_TEXTURE_FORMATS = 0x86A2;
+ public static final int GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+ public static final int GL_DONT_CARE = 0x1100;
+ public static final int GL_FASTEST = 0x1101;
+ public static final int GL_NICEST = 0x1102;
+ public static final int GL_GENERATE_MIPMAP_HINT = 0x8192;
+ public static final int GL_BYTE = 0x1400;
+ public static final int GL_UNSIGNED_BYTE = 0x1401;
+ public static final int GL_SHORT = 0x1402;
+ public static final int GL_UNSIGNED_SHORT = 0x1403;
+ public static final int GL_INT = 0x1404;
+ public static final int GL_UNSIGNED_INT = 0x1405;
+ public static final int GL_FLOAT = 0x1406;
+ public static final int GL_FIXED = 0x140C;
+ public static final int GL_DEPTH_COMPONENT = 0x1902;
+ public static final int GL_ALPHA = 0x1906;
+ public static final int GL_RGB = 0x1907;
+ public static final int GL_RGBA = 0x1908;
+ public static final int GL_LUMINANCE = 0x1909;
+ public static final int GL_LUMINANCE_ALPHA = 0x190A;
+ public static final int GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ public static final int GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ public static final int GL_UNSIGNED_SHORT_5_6_5 = 0x8363;
+ public static final int GL_FRAGMENT_SHADER = 0x8B30;
+ public static final int GL_VERTEX_SHADER = 0x8B31;
+ public static final int GL_MAX_VERTEX_ATTRIBS = 0x8869;
+ public static final int GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ public static final int GL_MAX_VARYING_VECTORS = 0x8DFC;
+ public static final int GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ public static final int GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ public static final int GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ public static final int GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ public static final int GL_SHADER_TYPE = 0x8B4F;
+ public static final int GL_DELETE_STATUS = 0x8B80;
+ public static final int GL_LINK_STATUS = 0x8B82;
+ public static final int GL_VALIDATE_STATUS = 0x8B83;
+ public static final int GL_ATTACHED_SHADERS = 0x8B85;
+ public static final int GL_ACTIVE_UNIFORMS = 0x8B86;
+ public static final int GL_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87;
+ public static final int GL_ACTIVE_ATTRIBUTES = 0x8B89;
+ public static final int GL_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A;
+ public static final int GL_SHADING_LANGUAGE_VERSION = 0x8B8C;
+ public static final int GL_CURRENT_PROGRAM = 0x8B8D;
+ public static final int GL_NEVER = 0x0200;
+ public static final int GL_LESS = 0x0201;
+ public static final int GL_EQUAL = 0x0202;
+ public static final int GL_LEQUAL = 0x0203;
+ public static final int GL_GREATER = 0x0204;
+ public static final int GL_NOTEQUAL = 0x0205;
+ public static final int GL_GEQUAL = 0x0206;
+ public static final int GL_ALWAYS = 0x0207;
+ public static final int GL_KEEP = 0x1E00;
+ public static final int GL_REPLACE = 0x1E01;
+ public static final int GL_INCR = 0x1E02;
+ public static final int GL_DECR = 0x1E03;
+ public static final int GL_INVERT = 0x150A;
+ public static final int GL_INCR_WRAP = 0x8507;
+ public static final int GL_DECR_WRAP = 0x8508;
+ public static final int GL_VENDOR = 0x1F00;
+ public static final int GL_RENDERER = 0x1F01;
+ public static final int GL_VERSION = 0x1F02;
+ public static final int GL_EXTENSIONS = 0x1F03;
+ public static final int GL_NEAREST = 0x2600;
+ public static final int GL_LINEAR = 0x2601;
+ public static final int GL_NEAREST_MIPMAP_NEAREST = 0x2700;
+ public static final int GL_LINEAR_MIPMAP_NEAREST = 0x2701;
+ public static final int GL_NEAREST_MIPMAP_LINEAR = 0x2702;
+ public static final int GL_LINEAR_MIPMAP_LINEAR = 0x2703;
+ public static final int GL_TEXTURE_MAG_FILTER = 0x2800;
+ public static final int GL_TEXTURE_MIN_FILTER = 0x2801;
+ public static final int GL_TEXTURE_WRAP_S = 0x2802;
+ public static final int GL_TEXTURE_WRAP_T = 0x2803;
+ public static final int GL_TEXTURE = 0x1702;
+ public static final int GL_TEXTURE_CUBE_MAP = 0x8513;
+ public static final int GL_TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ public static final int GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+ public static final int GL_TEXTURE0 = 0x84C0;
+ public static final int GL_TEXTURE1 = 0x84C1;
+ public static final int GL_TEXTURE2 = 0x84C2;
+ public static final int GL_TEXTURE3 = 0x84C3;
+ public static final int GL_TEXTURE4 = 0x84C4;
+ public static final int GL_TEXTURE5 = 0x84C5;
+ public static final int GL_TEXTURE6 = 0x84C6;
+ public static final int GL_TEXTURE7 = 0x84C7;
+ public static final int GL_TEXTURE8 = 0x84C8;
+ public static final int GL_TEXTURE9 = 0x84C9;
+ public static final int GL_TEXTURE10 = 0x84CA;
+ public static final int GL_TEXTURE11 = 0x84CB;
+ public static final int GL_TEXTURE12 = 0x84CC;
+ public static final int GL_TEXTURE13 = 0x84CD;
+ public static final int GL_TEXTURE14 = 0x84CE;
+ public static final int GL_TEXTURE15 = 0x84CF;
+ public static final int GL_TEXTURE16 = 0x84D0;
+ public static final int GL_TEXTURE17 = 0x84D1;
+ public static final int GL_TEXTURE18 = 0x84D2;
+ public static final int GL_TEXTURE19 = 0x84D3;
+ public static final int GL_TEXTURE20 = 0x84D4;
+ public static final int GL_TEXTURE21 = 0x84D5;
+ public static final int GL_TEXTURE22 = 0x84D6;
+ public static final int GL_TEXTURE23 = 0x84D7;
+ public static final int GL_TEXTURE24 = 0x84D8;
+ public static final int GL_TEXTURE25 = 0x84D9;
+ public static final int GL_TEXTURE26 = 0x84DA;
+ public static final int GL_TEXTURE27 = 0x84DB;
+ public static final int GL_TEXTURE28 = 0x84DC;
+ public static final int GL_TEXTURE29 = 0x84DD;
+ public static final int GL_TEXTURE30 = 0x84DE;
+ public static final int GL_TEXTURE31 = 0x84DF;
+ public static final int GL_REPEAT = 0x2901;
+ public static final int GL_CLAMP_TO_EDGE = 0x812F;
+ public static final int GL_MIRRORED_REPEAT = 0x8370;
+ public static final int GL_FLOAT_VEC2 = 0x8B50;
+ public static final int GL_FLOAT_VEC3 = 0x8B51;
+ public static final int GL_FLOAT_VEC4 = 0x8B52;
+ public static final int GL_INT_VEC2 = 0x8B53;
+ public static final int GL_INT_VEC3 = 0x8B54;
+ public static final int GL_INT_VEC4 = 0x8B55;
+ public static final int GL_BOOL = 0x8B56;
+ public static final int GL_BOOL_VEC2 = 0x8B57;
+ public static final int GL_BOOL_VEC3 = 0x8B58;
+ public static final int GL_BOOL_VEC4 = 0x8B59;
+ public static final int GL_FLOAT_MAT2 = 0x8B5A;
+ public static final int GL_FLOAT_MAT3 = 0x8B5B;
+ public static final int GL_FLOAT_MAT4 = 0x8B5C;
+ public static final int GL_SAMPLER_2D = 0x8B5E;
+ public static final int GL_SAMPLER_CUBE = 0x8B60;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ public static final int GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+ public static final int GL_IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+ public static final int GL_IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+ public static final int GL_COMPILE_STATUS = 0x8B81;
+ public static final int GL_INFO_LOG_LENGTH = 0x8B84;
+ public static final int GL_SHADER_SOURCE_LENGTH = 0x8B88;
+ public static final int GL_SHADER_COMPILER = 0x8DFA;
+ public static final int GL_SHADER_BINARY_FORMATS = 0x8DF8;
+ public static final int GL_NUM_SHADER_BINARY_FORMATS = 0x8DF9;
+ public static final int GL_LOW_FLOAT = 0x8DF0;
+ public static final int GL_MEDIUM_FLOAT = 0x8DF1;
+ public static final int GL_HIGH_FLOAT = 0x8DF2;
+ public static final int GL_LOW_INT = 0x8DF3;
+ public static final int GL_MEDIUM_INT = 0x8DF4;
+ public static final int GL_HIGH_INT = 0x8DF5;
+ public static final int GL_FRAMEBUFFER = 0x8D40;
+ public static final int GL_RENDERBUFFER = 0x8D41;
+ public static final int GL_RGBA4 = 0x8056;
+ public static final int GL_RGB5_A1 = 0x8057;
+ public static final int GL_RGB565 = 0x8D62;
+ public static final int GL_DEPTH_COMPONENT16 = 0x81A5;
+ public static final int GL_STENCIL_INDEX = 0x1901;
+ public static final int GL_STENCIL_INDEX8 = 0x8D48;
+ public static final int GL_RENDERBUFFER_WIDTH = 0x8D42;
+ public static final int GL_RENDERBUFFER_HEIGHT = 0x8D43;
+ public static final int GL_RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ public static final int GL_RENDERBUFFER_RED_SIZE = 0x8D50;
+ public static final int GL_RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ public static final int GL_RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ public static final int GL_RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ public static final int GL_RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ public static final int GL_RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+ public static final int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ public static final int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ public static final int GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ public static final int GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+ public static final int GL_COLOR_ATTACHMENT0 = 0x8CE0;
+ public static final int GL_DEPTH_ATTACHMENT = 0x8D00;
+ public static final int GL_STENCIL_ATTACHMENT = 0x8D20;
+ public static final int GL_NONE = 0;
+ public static final int GL_FRAMEBUFFER_COMPLETE = 0x8CD5;
+ public static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ public static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ public static final int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ public static final int GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+ public static final int GL_FRAMEBUFFER_BINDING = 0x8CA6;
+ public static final int GL_RENDERBUFFER_BINDING = 0x8CA7;
+ public static final int GL_MAX_RENDERBUFFER_SIZE = 0x84E8;
+ public static final int GL_INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ native private static void _nativeClassInit();
+ static {
+ _nativeClassInit();
+ }
diff --git a/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp
new file mode 100644
index 0000000..e451e9a
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp
@@ -0,0 +1,150 @@
+**
+** 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.
+*/
+
+// This source file is automatically generated
+
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/misc.h>
+
+#include <assert.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+static int initialized = 0;
+
+static jclass nioAccessClass;
+static jclass bufferClass;
+static jclass OOMEClass;
+static jclass UOEClass;
+static jclass IAEClass;
+static jclass AIOOBEClass;
+static jmethodID getBasePointerID;
+static jmethodID getBaseArrayID;
+static jmethodID getBaseArrayOffsetID;
+static jfieldID positionID;
+static jfieldID limitID;
+static jfieldID elementSizeShiftID;
+
+/* Cache method IDs each time the class is loaded. */
+
+static void
+nativeClassInitBuffer(JNIEnv *_env)
+{
+ jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
+ nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
+
+ jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
+ bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
+
+ getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
+ "getBasePointer", "(Ljava/nio/Buffer;)J");
+ getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
+ "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
+ getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
+ "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
+
+ positionID = _env->GetFieldID(bufferClass, "position", "I");
+ limitID = _env->GetFieldID(bufferClass, "limit", "I");
+ elementSizeShiftID =
+ _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
+}
+
+
+static void
+nativeClassInit(JNIEnv *_env, jclass glImplClass)
+{
+ nativeClassInitBuffer(_env);
+
+ jclass IAEClassLocal =
+ _env->FindClass("java/lang/IllegalArgumentException");
+ jclass OOMEClassLocal =
+ _env->FindClass("java/lang/OutOfMemoryError");
+ jclass UOEClassLocal =
+ _env->FindClass("java/lang/UnsupportedOperationException");
+ jclass AIOOBEClassLocal =
+ _env->FindClass("java/lang/ArrayIndexOutOfBoundsException");
+
+ IAEClass = (jclass) _env->NewGlobalRef(IAEClassLocal);
+ OOMEClass = (jclass) _env->NewGlobalRef(OOMEClassLocal);
+ UOEClass = (jclass) _env->NewGlobalRef(UOEClassLocal);
+ AIOOBEClass = (jclass) _env->NewGlobalRef(AIOOBEClassLocal);
+}
+
+static void *
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining)
+{
+ jint position;
+ jint limit;
+ jint elementSizeShift;
+ jlong pointer;
+ jint offset;
+ void *data;
+
+ position = _env->GetIntField(buffer, positionID);
+ limit = _env->GetIntField(buffer, limitID);
+ elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ *remaining = (limit - position) << elementSizeShift;
+ pointer = _env->CallStaticLongMethod(nioAccessClass,
+ getBasePointerID, buffer);
+ if (pointer != 0L) {
+ *array = NULL;
+ return (void *) (jint) pointer;
+ }
+
+ *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
+ getBaseArrayID, buffer);
+ offset = _env->CallStaticIntMethod(nioAccessClass,
+ getBaseArrayOffsetID, buffer);
+ data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
+
+ return (void *) ((char *) data + offset);
+}
+
+
+static void
+releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
+{
+ _env->ReleasePrimitiveArrayCritical(array, data,
+ commit ? 0 : JNI_ABORT);
+}
+
+static void *
+getDirectBufferPointer(JNIEnv *_env, jobject buffer) {
+ char* buf = (char*) _env->GetDirectBufferAddress(buffer);
+ if (buf) {
+ jint position = _env->GetIntField(buffer, positionID);
+ jint elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+ buf += position << elementSizeShift;
+ } else {
+ _env->ThrowNew(IAEClass, "Must use a native order direct Buffer");
+ }
+ return (void*) buf;
+}
+
+static int
+getNumCompressedTextureFormats() {
+ int numCompressedTextureFormats = 0;
+ glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedTextureFormats);
+ return numCompressedTextureFormats;
+}
+
+static void glVertexAttribPointerBounds(GLuint indx, GLint size, GLenum type,
+ GLboolean normalized, GLsizei stride, const GLvoid *pointer, GLsizei count) {
+ glVertexAttribPointer(indx, size, type, normalized, stride, pointer);
+}
+
+// --------------------------------------------------------------------------
+
diff --git a/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.cpp b/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.cpp
new file mode 100644
index 0000000..d92f515
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.cpp
@@ -0,0 +1,27 @@
+#include <string.h>
+
+/* void glGetProgramInfoLog ( GLuint shader, GLsizei maxLength, GLsizei* length, GLchar* infoLog ) */
+static
+jstring
+android_glGetProgramInfoLog (JNIEnv *_env, jobject _this, jint shader) {
+ GLint infoLen = 0;
+ jstring _result = 0;
+ char* buf = 0;
+ glGetProgramiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf == 0) {
+ _env->ThrowNew(IAEClass, "out of memory");
+ goto exit;
+ }
+ glGetProgramInfoLog(shader, infoLen, NULL, buf);
+ _result = _env->NewStringUTF(buf);
+ } else {
+ _result = _env->NewStringUTF("");
+ }
+exit:
+ if (buf) {
+ free(buf);
+ }
+ return _result;
+}
\ No newline at end of file
diff --git a/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.java b/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.java
new file mode 100644
index 0000000..19504f2
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.java
@@ -0,0 +1,6 @@
+ // C function void glGetProgramInfoLog( GLuint program, GLsizei maxLength, GLsizei * length,
+ // GLchar * infoLog);
+
+ public static native String glGetProgramInfoLog(
+ int program
+ );
diff --git a/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.nativeReg b/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.nativeReg
new file mode 100644
index 0000000..8553f2d
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glGetProgramInfoLog.nativeReg
@@ -0,0 +1 @@
+{"glGetProgramInfoLog", "(I)Ljava/lang/String;", (void *) android_glGetProgramInfoLog },
diff --git a/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.cpp b/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.cpp
new file mode 100644
index 0000000..5441d66
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.cpp
@@ -0,0 +1,27 @@
+#include <string.h>
+
+/* void glGetShaderInfoLog ( GLuint shader, GLsizei maxLength, GLsizei* length, GLchar* infoLog ) */
+static
+jstring
+android_glGetShaderInfoLog (JNIEnv *_env, jobject _this, jint shader) {
+ GLint infoLen = 0;
+ jstring _result = 0;
+ char* buf = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf == 0) {
+ _env->ThrowNew(IAEClass, "out of memory");
+ goto exit;
+ }
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ _result = _env->NewStringUTF(buf);
+ } else {
+ _result = _env->NewStringUTF("");
+ }
+exit:
+ if (buf) {
+ free(buf);
+ }
+ return _result;
+}
\ No newline at end of file
diff --git a/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.java b/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.java
new file mode 100644
index 0000000..1fac6be
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.java
@@ -0,0 +1,6 @@
+ // C function void glGetShaderInfoLog( GLuint shader, GLsizei maxLength, GLsizei * length,
+ // GLchar * infoLog);
+
+ public static native String glGetShaderInfoLog(
+ int shader
+ );
diff --git a/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.nativeReg b/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.nativeReg
new file mode 100644
index 0000000..71163c3
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glGetShaderInfoLog.nativeReg
@@ -0,0 +1 @@
+{"glGetShaderInfoLog", "(I)Ljava/lang/String;", (void *) android_glGetShaderInfoLog },
diff --git a/opengl/tools/glgen/stubs/gles11/glShaderSource.cpp b/opengl/tools/glgen/stubs/gles11/glShaderSource.cpp
new file mode 100644
index 0000000..c274108
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glShaderSource.cpp
@@ -0,0 +1,17 @@
+
+/* void glShaderSource ( GLuint shader, GLsizei count, const GLchar ** string, const GLint * length ) */
+static
+void
+android_glShaderSource
+ (JNIEnv *_env, jobject _this, jint shader, jstring string) {
+
+ if (!string) {
+ _env->ThrowNew(IAEClass, "string == null");
+ return;
+ }
+
+ const char* nativeString = _env->GetStringUTFChars(string, 0);
+ const char* strings[] = {nativeString};
+ glShaderSource(shader, 1, strings, 0);
+ _env->ReleaseStringUTFChars(string, nativeString);
+}
diff --git a/opengl/tools/glgen/stubs/gles11/glShaderSource.java b/opengl/tools/glgen/stubs/gles11/glShaderSource.java
new file mode 100644
index 0000000..a9c338a
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glShaderSource.java
@@ -0,0 +1,6 @@
+ // C function void glShaderSource ( GLuint shader, GLsizei count, const GLchar ** string, const GLint* length )
+
+ public static native void glShaderSource(
+ int shader,
+ String string
+ );
diff --git a/opengl/tools/glgen/stubs/gles11/glShaderSource.nativeReg b/opengl/tools/glgen/stubs/gles11/glShaderSource.nativeReg
new file mode 100644
index 0000000..b17783a
--- /dev/null
+++ b/opengl/tools/glgen/stubs/gles11/glShaderSource.nativeReg
@@ -0,0 +1 @@
+{"glShaderSource", "(ILjava/lang/String;)V", (void *) android_glShaderSource },
diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
index 4494643..b3d1c6c 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
+++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp
@@ -34,6 +34,12 @@
GLsizei stride, const GLvoid *pointer, GLsizei count);
GL_API void GL_APIENTRY glVertexPointerBounds(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glPointSizePointerOESBounds(GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glMatrixIndexPointerOESBounds(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count);
+GL_API void GL_APIENTRY glWeightPointerOESBounds(GLint size, GLenum type,
+ GLsizei stride, const GLvoid *pointer, GLsizei count);
}
static int initialized = 0;
diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
index fe60c5d..76fea3f 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
+++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
@@ -44,6 +44,9 @@
Buffer _normalPointer = null;
Buffer _texCoordPointer = null;
Buffer _vertexPointer = null;
+ Buffer _pointSizePointerOES = null;
+ Buffer _matrixIndexPointerOES = null;
+ Buffer _weightPointerOES = null;
public GLImpl() {
}