summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/camera/Android.mk1
-rw-r--r--libs/camera/Camera.cpp16
-rw-r--r--libs/camera/ICamera.cpp36
-rw-r--r--libs/gui/Android.mk11
-rw-r--r--libs/gui/IGraphicBufferAlloc.cpp (renamed from libs/surfaceflinger_client/IGraphicBufferAlloc.cpp)0
-rw-r--r--libs/gui/ISurface.cpp (renamed from libs/surfaceflinger_client/ISurface.cpp)0
-rw-r--r--libs/gui/ISurfaceComposer.cpp (renamed from libs/surfaceflinger_client/ISurfaceComposer.cpp)0
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp (renamed from libs/surfaceflinger_client/ISurfaceComposerClient.cpp)0
-rw-r--r--libs/gui/ISurfaceTexture.cpp7
-rw-r--r--libs/gui/LayerState.cpp (renamed from libs/surfaceflinger_client/LayerState.cpp)0
-rw-r--r--libs/gui/SharedBufferStack.cpp (renamed from libs/surfaceflinger_client/SharedBufferStack.cpp)0
-rw-r--r--libs/gui/Surface.cpp (renamed from libs/surfaceflinger_client/Surface.cpp)15
-rw-r--r--libs/gui/SurfaceComposerClient.cpp (renamed from libs/surfaceflinger_client/SurfaceComposerClient.cpp)0
-rw-r--r--libs/gui/SurfaceTexture.cpp24
-rw-r--r--libs/gui/SurfaceTextureClient.cpp29
-rw-r--r--libs/gui/tests/Android.mk2
-rw-r--r--libs/gui/tests/Surface_test.cpp (renamed from libs/surfaceflinger_client/tests/Surface_test.cpp)0
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/Debug.h4
-rw-r--r--libs/hwui/DisplayListRenderer.cpp35
-rw-r--r--libs/hwui/DisplayListRenderer.h19
-rw-r--r--libs/hwui/Layer.h5
-rw-r--r--libs/hwui/LayerRenderer.cpp18
-rw-r--r--libs/hwui/OpenGLRenderer.cpp142
-rw-r--r--libs/hwui/OpenGLRenderer.h5
-rw-r--r--libs/hwui/PathCache.h4
-rw-r--r--libs/hwui/ProgramCache.cpp44
-rw-r--r--libs/hwui/ProgramCache.h13
-rw-r--r--libs/hwui/Properties.h2
-rw-r--r--libs/hwui/ShapeCache.h16
-rw-r--r--libs/hwui/utils/GenerationCache.h245
-rw-r--r--libs/rs/Android.mk5
-rw-r--r--libs/rs/RenderScript.h295
-rw-r--r--libs/rs/RenderScriptDefines.h325
-rw-r--r--libs/rs/driver/rsdBcc.cpp549
-rw-r--r--libs/rs/driver/rsdBcc.h70
-rw-r--r--libs/rs/driver/rsdCore.cpp186
-rw-r--r--libs/rs/driver/rsdCore.h55
-rw-r--r--libs/rs/rs.spec12
-rw-r--r--libs/rs/rsAllocation.cpp176
-rw-r--r--libs/rs/rsAllocation.h43
-rw-r--r--libs/rs/rsContext.cpp97
-rw-r--r--libs/rs/rsContext.h33
-rw-r--r--libs/rs/rsScript.cpp47
-rw-r--r--libs/rs/rsScript.h49
-rw-r--r--libs/rs/rsScriptC.cpp488
-rw-r--r--libs/rs/rsScriptC.h23
-rw-r--r--libs/rs/rsScriptC_Lib.cpp157
-rw-r--r--libs/rs/rsScriptC_LibGL.cpp4
-rw-r--r--libs/rs/rs_hal.h104
-rw-r--r--libs/surfaceflinger_client/Android.mk17
-rw-r--r--libs/surfaceflinger_client/tests/Android.mk53
-rw-r--r--libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk17
-rw-r--r--libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp284
-rw-r--r--libs/ui/Input.cpp237
-rw-r--r--libs/ui/InputTransport.cpp4
-rw-r--r--libs/utils/AssetManager.cpp2
-rw-r--r--libs/utils/Looper.cpp19
-rw-r--r--libs/utils/Timers.cpp18
59 files changed, 2203 insertions, 1860 deletions
diff --git a/libs/camera/Android.mk b/libs/camera/Android.mk
index 2f16923de473..b17b3d22044d 100644
--- a/libs/camera/Android.mk
+++ b/libs/camera/Android.mk
@@ -13,7 +13,6 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
libhardware \
- libsurfaceflinger_client \
libui \
libgui
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index e2883121e497..5eb48da3589e 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -205,22 +205,6 @@ status_t Camera::startPreview()
return c->startPreview();
}
-int32_t Camera::getNumberOfVideoBuffers() const
-{
- LOGV("getNumberOfVideoBuffers");
- sp <ICamera> c = mCamera;
- if (c == 0) return 0;
- return c->getNumberOfVideoBuffers();
-}
-
-sp<IMemory> Camera::getVideoBuffer(int32_t index) const
-{
- LOGV("getVideoBuffer: %d", index);
- sp <ICamera> c = mCamera;
- if (c == 0) return 0;
- return c->getVideoBuffer(index);
-}
-
status_t Camera::storeMetaDataInBuffers(bool enabled)
{
LOGV("storeMetaDataInBuffers: %s",
diff --git a/libs/camera/ICamera.cpp b/libs/camera/ICamera.cpp
index 931b57d048aa..5f6e5ef4d129 100644
--- a/libs/camera/ICamera.cpp
+++ b/libs/camera/ICamera.cpp
@@ -46,8 +46,6 @@ enum {
STOP_RECORDING,
RECORDING_ENABLED,
RELEASE_RECORDING_FRAME,
- GET_NUM_VIDEO_BUFFERS,
- GET_VIDEO_BUFFER,
STORE_META_DATA_IN_BUFFERS,
};
@@ -149,27 +147,6 @@ public:
remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
}
- int32_t getNumberOfVideoBuffers() const
- {
- LOGV("getNumberOfVideoBuffers");
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- remote()->transact(GET_NUM_VIDEO_BUFFERS, data, &reply);
- return reply.readInt32();
- }
-
- sp<IMemory> getVideoBuffer(int32_t index) const
- {
- LOGV("getVideoBuffer: %d", index);
- Parcel data, reply;
- data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
- data.writeInt32(index);
- remote()->transact(GET_VIDEO_BUFFER, data, &reply);
- sp<IMemory> mem = interface_cast<IMemory>(
- reply.readStrongBinder());
- return mem;
- }
-
status_t storeMetaDataInBuffers(bool enabled)
{
LOGV("storeMetaDataInBuffers: %s", enabled? "true": "false");
@@ -355,19 +332,6 @@ status_t BnCamera::onTransact(
releaseRecordingFrame(mem);
return NO_ERROR;
} break;
- case GET_NUM_VIDEO_BUFFERS: {
- LOGV("GET_NUM_VIDEO_BUFFERS");
- CHECK_INTERFACE(ICamera, data, reply);
- reply->writeInt32(getNumberOfVideoBuffers());
- return NO_ERROR;
- } break;
- case GET_VIDEO_BUFFER: {
- LOGV("GET_VIDEO_BUFFER");
- CHECK_INTERFACE(ICamera, data, reply);
- int32_t index = data.readInt32();
- reply->writeStrongBinder(getVideoBuffer(index)->asBinder());
- return NO_ERROR;
- } break;
case STORE_META_DATA_IN_BUFFERS: {
LOGV("STORE_META_DATA_IN_BUFFERS");
CHECK_INTERFACE(ICamera, data, reply);
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index d1a6af1dc11b..58bb0d31f4e2 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -10,7 +10,15 @@ LOCAL_SRC_FILES:= \
SensorEventQueue.cpp \
SensorManager.cpp \
SurfaceTexture.cpp \
- SurfaceTextureClient.cpp
+ SurfaceTextureClient.cpp \
+ ISurfaceComposer.cpp \
+ ISurface.cpp \
+ ISurfaceComposerClient.cpp \
+ IGraphicBufferAlloc.cpp \
+ LayerState.cpp \
+ SharedBufferStack.cpp \
+ Surface.cpp \
+ SurfaceComposerClient.cpp \
LOCAL_SHARED_LIBRARIES := \
libcutils \
@@ -21,7 +29,6 @@ LOCAL_SHARED_LIBRARIES := \
libui \
libEGL \
libGLESv2 \
- libsurfaceflinger_client
LOCAL_MODULE:= libgui
diff --git a/libs/surfaceflinger_client/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index e05da725c47f..e05da725c47f 100644
--- a/libs/surfaceflinger_client/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
diff --git a/libs/surfaceflinger_client/ISurface.cpp b/libs/gui/ISurface.cpp
index 23b90af31143..23b90af31143 100644
--- a/libs/surfaceflinger_client/ISurface.cpp
+++ b/libs/gui/ISurface.cpp
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 8951c3f0453a..8951c3f0453a 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 7730eb1fa91b..7730eb1fa91b 100644
--- a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index d661fd57914e..bc14ad55149c 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -88,10 +88,11 @@ public:
return result;
}
- virtual status_t queueBuffer(int buf) {
+ virtual status_t queueBuffer(int buf, int64_t timestamp) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(buf);
+ data.writeInt64(timestamp);
remote()->transact(QUEUE_BUFFER, data, &reply);
status_t result = reply.readInt32();
return result;
@@ -174,7 +175,8 @@ status_t BnSurfaceTexture::onTransact(
case QUEUE_BUFFER: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int buf = data.readInt32();
- status_t result = queueBuffer(buf);
+ int64_t timestamp = data.readInt64();
+ status_t result = queueBuffer(buf, timestamp);
reply->writeInt32(result);
return NO_ERROR;
} break;
@@ -196,7 +198,6 @@ status_t BnSurfaceTexture::onTransact(
return NO_ERROR;
} break;
case SET_TRANSFORM: {
- Rect reg;
CHECK_INTERFACE(ISurfaceTexture, data, reply);
uint32_t transform = data.readInt32();
status_t result = setTransform(transform);
diff --git a/libs/surfaceflinger_client/LayerState.cpp b/libs/gui/LayerState.cpp
index 01c4c7ebfe84..01c4c7ebfe84 100644
--- a/libs/surfaceflinger_client/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/gui/SharedBufferStack.cpp
index 7505d530e0c5..7505d530e0c5 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/gui/SharedBufferStack.cpp
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/gui/Surface.cpp
index 21d509a6a8df..0dfbf01aa449 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -753,6 +753,9 @@ int Surface::perform(int operation, va_list args)
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
res = dispatch_set_buffers_transform( args );
break;
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ res = dispatch_set_buffers_timestamp( args );
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -792,6 +795,11 @@ int Surface::dispatch_set_buffers_transform(va_list args) {
return setBuffersTransform(transform);
}
+int Surface::dispatch_set_buffers_timestamp(va_list args) {
+ int64_t timestamp = va_arg(args, int64_t);
+ return setBuffersTimestamp(timestamp);
+}
+
void Surface::setUsage(uint32_t reqUsage)
{
Mutex::Autolock _l(mSurfaceLock);
@@ -910,6 +918,13 @@ int Surface::setBuffersTransform(int transform)
return NO_ERROR;
}
+int Surface::setBuffersTimestamp(int64_t timestamp)
+{
+ // Surface doesn't really have anything meaningful to do with timestamps
+ // so they'll just be dropped here.
+ return NO_ERROR;
+}
+
// ----------------------------------------------------------------------------
int Surface::getConnectedApi() const
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d3367246a119..d3367246a119 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 5c6d71b1501b..cdaca47b6564 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -76,9 +76,15 @@ static float mtxRot270[16] = {
static void mtxMul(float out[16], const float a[16], const float b[16]);
SurfaceTexture::SurfaceTexture(GLuint tex) :
- mBufferCount(MIN_BUFFER_SLOTS), mCurrentTexture(INVALID_BUFFER_SLOT),
- mCurrentTransform(0), mLastQueued(INVALID_BUFFER_SLOT),
- mLastQueuedTransform(0), mNextTransform(0), mTexName(tex) {
+ mBufferCount(MIN_BUFFER_SLOTS),
+ mCurrentTexture(INVALID_BUFFER_SLOT),
+ mCurrentTransform(0),
+ mCurrentTimestamp(0),
+ mLastQueued(INVALID_BUFFER_SLOT),
+ mLastQueuedTransform(0),
+ mLastQueuedTimestamp(0),
+ mNextTransform(0),
+ mTexName(tex) {
LOGV("SurfaceTexture::SurfaceTexture");
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
@@ -153,7 +159,7 @@ status_t SurfaceTexture::dequeueBuffer(int *buf) {
return OK;
}
-status_t SurfaceTexture::queueBuffer(int buf) {
+status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
LOGV("SurfaceTexture::queueBuffer");
Mutex::Autolock lock(mMutex);
if (buf < 0 || mBufferCount <= buf) {
@@ -172,6 +178,7 @@ status_t SurfaceTexture::queueBuffer(int buf) {
mLastQueued = buf;
mLastQueuedCrop = mNextCrop;
mLastQueuedTransform = mNextTransform;
+ mLastQueuedTimestamp = timestamp;
if (mFrameAvailableListener != 0) {
mFrameAvailableListener->onFrameAvailable();
}
@@ -246,12 +253,13 @@ status_t SurfaceTexture::updateTexImage() {
mCurrentTextureBuf = mSlots[mCurrentTexture].mGraphicBuffer;
mCurrentCrop = mLastQueuedCrop;
mCurrentTransform = mLastQueuedTransform;
+ mCurrentTimestamp = mLastQueuedTimestamp;
}
return OK;
}
void SurfaceTexture::getTransformMatrix(float mtx[16]) {
- LOGV("SurfaceTexture::updateTexImage");
+ LOGV("SurfaceTexture::getTransformMatrix");
Mutex::Autolock lock(mMutex);
float xform[16];
@@ -342,6 +350,12 @@ void SurfaceTexture::getTransformMatrix(float mtx[16]) {
mtxMul(mtx, mtxFlipV, mtxBeforeFlipV);
}
+nsecs_t SurfaceTexture::getTimestamp() {
+ LOGV("SurfaceTexture::getTimestamp");
+ Mutex::Autolock lock(mMutex);
+ return mCurrentTimestamp;
+}
+
void SurfaceTexture::setFrameAvailableListener(
const sp<FrameAvailableListener>& l) {
LOGV("SurfaceTexture::setFrameAvailableListener");
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 7f1d9cbf22c5..a4812d073546 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -26,7 +26,8 @@ namespace android {
SurfaceTextureClient::SurfaceTextureClient(
const sp<ISurfaceTexture>& surfaceTexture):
mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(1),
- mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() {
+ mReqHeight(1), mReqFormat(DEFAULT_FORMAT), mReqUsage(0),
+ mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO), mMutex() {
// Initialize the ANativeWindow function pointers.
ANativeWindow::setSwapInterval = setSwapInterval;
ANativeWindow::dequeueBuffer = dequeueBuffer;
@@ -135,9 +136,17 @@ int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
LOGV("SurfaceTextureClient::queueBuffer");
Mutex::Autolock lock(mMutex);
+ int64_t timestamp;
+ if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
+ timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ LOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
+ timestamp / 1000000.f);
+ } else {
+ timestamp = mTimestamp;
+ }
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (mSlots[i]->handle == buffer->handle) {
- return mSurfaceTexture->queueBuffer(i);
+ return mSurfaceTexture->queueBuffer(i, timestamp);
}
}
LOGE("queueBuffer: unknown buffer queued");
@@ -196,6 +205,9 @@ int SurfaceTextureClient::perform(int operation, va_list args)
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
res = dispatchSetBuffersTransform(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ res = dispatchSetBuffersTimestamp(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -240,6 +252,11 @@ int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) {
return setBuffersTransform(transform);
}
+int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) {
+ int64_t timestamp = va_arg(args, int64_t);
+ return setBuffersTimestamp(timestamp);
+}
+
int SurfaceTextureClient::connect(int api) {
LOGV("SurfaceTextureClient::connect");
// XXX: Implement this!
@@ -323,6 +340,14 @@ int SurfaceTextureClient::setBuffersTransform(int transform)
return err;
}
+int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
+{
+ LOGV("SurfaceTextureClient::setBuffersTimestamp");
+ Mutex::Autolock lock(mMutex);
+ mTimestamp = timestamp;
+ return NO_ERROR;
+}
+
void SurfaceTextureClient::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i] = 0;
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 7516299446ab..ecd09951153e 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -9,6 +9,7 @@ LOCAL_MODULE := SurfaceTexture_test
LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := \
+ Surface_test.cpp \
SurfaceTextureClient_test.cpp \
SurfaceTexture_test.cpp \
@@ -20,7 +21,6 @@ LOCAL_SHARED_LIBRARIES := \
libcutils \
libgui \
libstlport \
- libsurfaceflinger_client \
libui \
libutils \
diff --git a/libs/surfaceflinger_client/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index fd07479a0587..fd07479a0587 100644
--- a/libs/surfaceflinger_client/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index f4a0161b2e1f..b465fee71a0a 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -42,7 +42,6 @@ ifeq ($(USE_OPENGL_RENDERER),true)
LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
LOCAL_MODULE := libhwui
LOCAL_MODULE_TAGS := optional
- LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 14471bc7b717..f74238e9e426 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -26,7 +26,7 @@
// Turn on to enable memory usage summary on each frame
#define DEBUG_MEMORY_USAGE 0
-// Turn on to enable layers debugging when renderered as regions
+// Turn on to enable layers debugging when rendered as regions
#define DEBUG_LAYERS_AS_REGIONS 0
// Turn on to display debug info about vertex/fragment shaders
@@ -35,7 +35,7 @@
// Turn on to display info about layers
#define DEBUG_LAYERS 0
-// Turn on to display debug infor about 9patch objects
+// Turn on to display debug info about 9patch objects
#define DEBUG_PATCHES 0
// Turn on to display vertex and tex coords data about 9patch objects
// This flag requires DEBUG_PATCHES to be turned on
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 868290bf0f8b..c7459d151816 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -53,6 +53,7 @@ const char* DisplayList::OP_NAMES[] = {
"DrawArc",
"DrawPath",
"DrawLines",
+ "DrawPoints",
"DrawText",
"ResetShader",
"SetupShader",
@@ -92,13 +93,11 @@ void DisplayList::clearResources() {
mPaints.clear();
for (size_t i = 0; i < mPaths.size(); i++) {
- delete mPaths.itemAt(i);
+ SkPath* path = mPaths.itemAt(i);
+ caches.pathCache.remove(path);
+ delete path;
}
mPaths.clear();
- for (size_t i = 0; i < mOriginalPaths.size(); i++) {
- caches.resourceCache.decrementRefcount(mOriginalPaths.itemAt(i));
- }
- mOriginalPaths.clear();
for (size_t i = 0; i < mMatrices.size(); i++) {
delete mMatrices.itemAt(i);
@@ -150,13 +149,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde
mPaths.add(paths.itemAt(i));
}
- const Vector<SkPath*> &originalPaths = recorder.getOriginalPaths();
- for (size_t i = 0; i < originalPaths.size(); i++) {
- SkPath* path = originalPaths.itemAt(i);
- mOriginalPaths.add(path);
- caches.resourceCache.incrementRefcount(path);
- }
-
const Vector<SkMatrix*> &matrices = recorder.getMatrices();
for (size_t i = 0; i < matrices.size(); i++) {
mMatrices.add(matrices.itemAt(i));
@@ -452,6 +444,13 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level)
renderer.drawLines(points, count, getPaint());
}
break;
+ case DrawPoints: {
+ int count = 0;
+ float* points = getFloats(count);
+ DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
+ renderer.drawPoints(points, count, getPaint());
+ }
+ break;
case DrawText: {
getText(&text);
int count = getInt();
@@ -533,12 +532,6 @@ void DisplayListRenderer::reset() {
}
mBitmapResources.clear();
- for (size_t i = 0; i < mOriginalPaths.size(); i++) {
- SkPath* resource = mOriginalPaths.itemAt(i);
- caches.resourceCache.decrementRefcount(resource);
- }
- mOriginalPaths.clear();
-
for (size_t i = 0; i < mShaders.size(); i++) {
caches.resourceCache.decrementRefcount(mShaders.itemAt(i));
}
@@ -804,6 +797,12 @@ void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
addPaint(paint);
}
+void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+ addOp(DisplayList::DrawPoints);
+ addFloats(points, count);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint) {
addOp(DisplayList::DrawText);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 6fc315c0c1d6..da57e4a59ed2 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -89,6 +89,7 @@ public:
DrawArc,
DrawPath,
DrawLines,
+ DrawPoints,
DrawText,
ResetShader,
SetupShader,
@@ -193,7 +194,6 @@ private:
Vector<SkPaint*> mPaints;
Vector<SkPath*> mPaths;
- Vector<SkPath*> mOriginalPaths;
Vector<SkMatrix*> mMatrices;
Vector<SkiaShader*> mShaders;
@@ -265,6 +265,7 @@ public:
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
void drawLines(float* points, int count, SkPaint* paint);
+ void drawPoints(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
void resetShader();
@@ -298,10 +299,6 @@ public:
return mPaths;
}
- const Vector<SkPath*>& getOriginalPaths() const {
- return mOriginalPaths;
- }
-
const Vector<SkMatrix*>& getMatrices() const {
return mMatrices;
}
@@ -383,16 +380,9 @@ private:
SkPath* pathCopy = mPathMap.valueFor(path);
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
- if (pathCopy == NULL) {
- pathCopy = path;
- mOriginalPaths.add(path);
- Caches& caches = Caches::getInstance();
- caches.resourceCache.incrementRefcount(path);
- } else {
- pathCopy = new SkPath(*path);
- mPaths.add(pathCopy);
- }
+ pathCopy = new SkPath(*path);
mPathMap.add(path, pathCopy);
+ mPaths.add(pathCopy);
}
addInt((int) pathCopy);
@@ -469,7 +459,6 @@ private:
Vector<SkPaint*> mPaints;
DefaultKeyedVector<SkPaint*, SkPaint*> mPaintMap;
- Vector<SkPath*> mOriginalPaths;
Vector<SkPath*> mPaths;
DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index bb2843790ed7..26e240f2be99 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -103,6 +103,11 @@ struct Layer {
* have been drawn.
*/
Region region;
+ /**
+ * If the region is a rectangle, coordinates of the
+ * region are stored here.
+ */
+ Rect regionRect;
/**
* Color filter used to draw this layer. Optional.
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index f92e20b841f9..ba110ec0efae 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -92,11 +92,7 @@ Region* LayerRenderer::getRegion() {
void LayerRenderer::generateMesh() {
#if RENDER_LAYERS_AS_REGIONS
-#if RENDER_LAYERS_RECT_AS_RECT
if (mLayer->region.isRect() || mLayer->region.isEmpty()) {
-#else
- if (mLayer->region.isEmpty()) {
-#endif
if (mLayer->mesh) {
delete mLayer->mesh;
delete mLayer->meshIndices;
@@ -105,6 +101,20 @@ void LayerRenderer::generateMesh() {
mLayer->meshIndices = NULL;
mLayer->meshElementCount = 0;
}
+
+ const android::Rect& bounds = mLayer->region.getBounds();
+ mLayer->regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
+ bounds.rightBottom().x, bounds.rightBottom().y);
+
+ const float texX = 1.0f / float(mLayer->width);
+ const float texY = 1.0f / float(mLayer->height);
+ const float height = mLayer->layer.getHeight();
+ mLayer->texCoords.set(
+ mLayer->regionRect.left * texX,
+ (height - mLayer->regionRect.top) * texY,
+ mLayer->regionRect.right * texX,
+ (height - mLayer->regionRect.bottom) * texY);
+
return;
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index d9d7d231a38f..6fabbef39451 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -646,13 +646,14 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap)
void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
#if RENDER_LAYERS_AS_REGIONS
-#if RENDER_LAYERS_RECT_AS_RECT
if (layer->region.isRect()) {
- composeLayerRect(layer, rect);
+ const android::Rect& bounds = layer->region.getBounds();
+ layer->regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
+ bounds.rightBottom().x, bounds.rightBottom().y);
+ composeLayerRect(layer, layer->regionRect);
layer->region.clear();
return;
}
-#endif
if (!layer->region.isEmpty()) {
size_t count;
@@ -881,6 +882,11 @@ void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) {
mDescription.hasAlpha8Texture = isAlpha8;
}
+void OpenGLRenderer::setupDrawPoint(float pointSize) {
+ mDescription.isPoint = true;
+ mDescription.pointSize = pointSize;
+}
+
void OpenGLRenderer::setupDrawColor(int color) {
setupDrawColor(color, (color >> 24) & 0xFF);
}
@@ -989,6 +995,11 @@ void OpenGLRenderer::setupDrawModelView(float left, float top, float right, floa
}
}
+void OpenGLRenderer::setupDrawPointUniforms() {
+ int slot = mCaches.currentProgram->getUniform("pointSize");
+ glUniform1f(slot, mDescription.pointSize);
+}
+
void OpenGLRenderer::setupDrawColorUniforms() {
if (mColorSet || (mShader && mSetShaderColor)) {
mCaches.currentProgram->setColor(mColorR, mColorG, mColorB, mColorA);
@@ -1072,6 +1083,44 @@ bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, u
return false;
}
+void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint) {
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+
+ float x = left;
+ float y = top;
+
+ bool ignoreTransform = false;
+ if (mSnapshot->transform->isPureTranslate()) {
+ x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
+ y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
+ ignoreTransform = true;
+ }
+
+ setupDraw();
+ setupDrawWithTexture(true);
+ if (paint) {
+ setupDrawAlpha8Color(paint->getColor(), alpha);
+ }
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(true, mode);
+ setupDrawProgram();
+ setupDrawModelView(x, y, x + texture->width, y + texture->height, ignoreTransform);
+ setupDrawTexture(texture->id);
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawShaderUniforms();
+ setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+ finishDrawTexture();
+}
+
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
const float right = left + bitmap->width();
const float bottom = top + bitmap->height();
@@ -1085,7 +1134,11 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint
if (!texture) return;
const AutoTexture autoCleanup(texture);
- drawTextureRect(left, top, right, bottom, texture, paint);
+ if (bitmap->getConfig() == SkBitmap::kA8_Config) {
+ drawAlphaBitmap(texture, left, top, paint);
+ } else {
+ drawTextureRect(left, top, right, bottom, texture, paint);
+ }
}
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
@@ -1388,26 +1441,66 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
} else {
// TODO: Handle the AA case
for (int i = 0; i < count; i += 4) {
- const float left = fmin(points[i], points[i + 1]);
- const float right = fmax(points[i], points[i + 1]);
- const float top = fmin(points[i + 2], points[i + 3]);
- const float bottom = fmax(points[i + 2], points[i + 3]);
+ TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
+ TextureVertex::set(vertex++, points[i + 2], points[i + 3], 0.0f, 0.0f);
- if (!quickReject(left, top, right, bottom)) {
- TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
- TextureVertex::set(vertex++, points[i + 2], points[i + 3], 0.0f, 0.0f);
+ generatedVerticesCount += 2;
- generatedVerticesCount += 2;
+ const float left = fmin(points[i], points[i + 2]);
+ const float right = fmax(points[i], points[i + 2]);
+ const float top = fmin(points[i + 1], points[i + 3]);
+ const float bottom = fmax(points[i + 1], points[i + 3]);
- dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
- }
+ dirtyLayer(left, top,
+ right == left ? left + 1 : right, bottom == top ? top + 1 : bottom,
+ *mSnapshot->transform);
}
- if (generatedVerticesCount > 0) {
- glLineWidth(1.0f);
- glDrawArrays(GL_LINES, 0, generatedVerticesCount);
- }
+ glLineWidth(1.0f);
+ glDrawArrays(GL_LINES, 0, generatedVerticesCount);
+ }
+}
+
+void OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ // TODO: The paint's cap style defines whether the points are square or circular
+ // TODO: Handle AA for round points
+
+ // A stroke width of 0 has a special meaningin Skia:
+ // it draws an unscaled 1px point
+ const bool isHairLine = paint->getStrokeWidth() == 0.0f;
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ int verticesCount = count >> 1;
+ int generatedVerticesCount = 0;
+
+ TextureVertex pointsData[verticesCount];
+ TextureVertex* vertex = &pointsData[0];
+
+ setupDraw();
+ setupDrawPoint(isHairLine ? 1.0f : paint->getStrokeWidth());
+ setupDrawColor(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(mode);
+ setupDrawProgram();
+ setupDrawModelViewIdentity();
+ setupDrawColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawPointUniforms();
+ setupDrawShaderIdentityUniforms();
+ setupDrawMesh(vertex);
+
+ for (int i = 0; i < count; i += 2) {
+ TextureVertex::set(vertex++, points[i], points[i + 1], 0.0f, 0.0f);
+ generatedVerticesCount++;
}
+
+ glDrawArrays(GL_POINTS, 0, generatedVerticesCount);
}
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -1658,14 +1751,9 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
#if RENDER_LAYERS_AS_REGIONS
if (!layer->region.isEmpty()) {
-#if RENDER_LAYERS_RECT_AS_RECT
if (layer->region.isRect()) {
- const Rect r(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight());
- composeLayerRect(layer, r);
+ composeLayerRect(layer, layer->regionRect);
} else if (layer->mesh) {
-#else
- if (layer->mesh) {
-#endif
const float a = alpha / 255.0f;
const Rect& rect = layer->layer;
@@ -1675,13 +1763,11 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
setupDrawColorFilter();
setupDrawBlending(layer->blend || layer->alpha < 255, layer->mode, false);
setupDrawProgram();
+ setupDrawModelViewTranslate(x, y,
+ x + layer->layer.getWidth(), y + layer->layer.getHeight());
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawTexture(layer->texture);
- // TODO: The current layer, if any, will be dirtied with the bounding box
- // of the layer we are drawing. Since the layer we are drawing has
- // a mesh, we know the dirty region, we should use it instead
- setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
setupDrawMesh(&layer->mesh[0].position[0], &layer->mesh[0].texture[0]);
glDrawElements(GL_TRIANGLES, layer->meshElementCount,
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 73624733df0a..4b93b8036cbb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -119,6 +119,7 @@ public:
float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
virtual void drawLines(float* points, int count, SkPaint* paint);
+ virtual void drawPoints(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
SkPaint* paint);
@@ -279,6 +280,8 @@ private:
void drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
void drawRectAsShape(float left, float top, float right, float bottom, SkPaint* p);
+ void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);
+
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
* are transformed by the current snapshot's transform matrix.
@@ -422,6 +425,7 @@ private:
* Various methods to setup OpenGL rendering.
*/
void setupDrawWithTexture(bool isAlpha8 = false);
+ void setupDrawPoint(float pointSize);
void setupDrawColor(int color);
void setupDrawColor(int color, int alpha);
void setupDrawColor(float r, float g, float b, float a);
@@ -440,6 +444,7 @@ private:
bool ignoreTransform = false, bool ignoreModelView = false);
void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
bool ignoreTransform = false);
+ void setupDrawPointUniforms();
void setupDrawColorUniforms();
void setupDrawPureColorUniforms();
void setupDrawShaderIdentityUniforms();
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index dc67e160fabf..7ff8b74810dd 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -41,8 +41,7 @@ struct PathCacheEntry: public ShapeCacheEntry {
path = NULL;
}
- PathCacheEntry(const PathCacheEntry& entry):
- ShapeCacheEntry(entry) {
+ PathCacheEntry(const PathCacheEntry& entry): ShapeCacheEntry(entry) {
path = entry.path;
}
@@ -55,6 +54,7 @@ struct PathCacheEntry: public ShapeCacheEntry {
}
SkPath* path;
+
}; // PathCacheEntry
/**
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 0b6c7b5c64d2..f0bc36bf447f 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -41,6 +41,8 @@ const char* gVS_Header_Attributes_TexCoords =
"attribute vec2 texCoords;\n";
const char* gVS_Header_Uniforms =
"uniform mat4 transform;\n";
+const char* gVS_Header_Uniforms_IsPoint =
+ "uniform mediump float pointSize;\n";
const char* gVS_Header_Uniforms_HasGradient[3] = {
// Linear
"uniform mat4 screenSpace;\n",
@@ -51,11 +53,13 @@ const char* gVS_Header_Uniforms_HasGradient[3] = {
};
const char* gVS_Header_Uniforms_HasBitmap =
"uniform mat4 textureTransform;\n"
- "uniform vec2 textureDimension;\n";
+ "uniform mediump vec2 textureDimension;\n";
const char* gVS_Header_Varyings_HasTexture =
"varying vec2 outTexCoords;\n";
const char* gVS_Header_Varyings_HasBitmap =
"varying vec2 outBitmapTexCoords;\n";
+const char* gVS_Header_Varyings_PointHasBitmap =
+ "varying vec2 outPointBitmapTexCoords;\n";
const char* gVS_Header_Varyings_HasGradient[3] = {
// Linear
"varying vec2 linear;\n",
@@ -78,8 +82,12 @@ const char* gVS_Main_OutGradient[3] = {
};
const char* gVS_Main_OutBitmapTexCoords =
" outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
+const char* gVS_Main_OutPointBitmapTexCoords =
+ " outPointBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n";
const char* gVS_Main_Position =
" gl_Position = transform * position;\n";
+const char* gVS_Main_PointSize =
+ " gl_PointSize = pointSize;\n";
const char* gVS_Footer =
"}\n\n";
@@ -93,6 +101,9 @@ const char* gFS_Header =
"precision mediump float;\n\n";
const char* gFS_Uniforms_Color =
"uniform vec4 color;\n";
+const char* gFS_Header_Uniforms_PointHasBitmap =
+ "uniform vec2 textureDimension;\n"
+ "uniform float pointSize;\n";
const char* gFS_Uniforms_TextureSampler =
"uniform sampler2D sampler;\n";
const char* gFS_Uniforms_GradientSampler[3] = {
@@ -121,6 +132,10 @@ const char* gFS_Main =
"\nvoid main(void) {\n"
" lowp vec4 fragColor;\n";
+const char* gFS_Main_PointBitmapTexCoords =
+ " vec2 outBitmapTexCoords = outPointBitmapTexCoords + "
+ "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n";
+
// Fast cases
const char* gFS_Fast_SingleColor =
"\nvoid main(void) {\n"
@@ -347,6 +362,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
if (description.hasBitmap) {
shader.append(gVS_Header_Uniforms_HasBitmap);
}
+ if (description.isPoint) {
+ shader.append(gVS_Header_Uniforms_IsPoint);
+ }
// Varyings
if (description.hasTexture) {
shader.append(gVS_Header_Varyings_HasTexture);
@@ -355,7 +373,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Header_Varyings_HasBitmap);
+ shader.append(description.isPoint ?
+ gVS_Header_Varyings_PointHasBitmap :
+ gVS_Header_Varyings_HasBitmap);
}
// Begin the shader
@@ -367,7 +387,12 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Main_OutGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Main_OutBitmapTexCoords);
+ shader.append(description.isPoint ?
+ gVS_Main_OutPointBitmapTexCoords :
+ gVS_Main_OutBitmapTexCoords);
+ }
+ if (description.isPoint) {
+ shader.append(gVS_Main_PointSize);
}
// Output transformed position
shader.append(gVS_Main_Position);
@@ -399,7 +424,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
- shader.append(gVS_Header_Varyings_HasBitmap);
+ shader.append(description.isPoint ?
+ gVS_Header_Varyings_PointHasBitmap :
+ gVS_Header_Varyings_HasBitmap);
}
// Uniforms
@@ -417,9 +444,13 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
if (description.hasGradient) {
shader.append(gFS_Uniforms_GradientSampler[description.gradientType]);
}
+ if (description.hasBitmap && description.isPoint) {
+ shader.append(gFS_Header_Uniforms_PointHasBitmap);
+ }
// Optimization for common cases
- if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone) {
+ if (!blendFramebuffer && description.colorOp == ProgramDescription::kColorNone &&
+ !description.isPoint) {
bool fast = false;
const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -507,6 +538,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gFS_Main_FetchGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ if (description.isPoint) {
+ shader.append(gFS_Main_PointBitmapTexCoords);
+ }
if (!description.isBitmapNpot) {
shader.append(gFS_Main_FetchBitmap);
} else {
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index ead5b920c1dc..737d91ba12f9 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -71,7 +71,9 @@ namespace uirenderer {
#define PROGRAM_BITMAP_WRAPT_SHIFT 11
#define PROGRAM_GRADIENT_TYPE_SHIFT 33
-#define PROGRAM_MODULATE 35
+#define PROGRAM_MODULATE_SHIFT 35
+
+#define PROGRAM_IS_POINT_SHIFT 36
///////////////////////////////////////////////////////////////////////////////
// Types
@@ -135,6 +137,9 @@ struct ProgramDescription {
SkXfermode::Mode framebufferMode;
bool swapSrcDst;
+ bool isPoint;
+ float pointSize;
+
/**
* Resets this description. All fields are reset back to the default
* values they hold after building a new instance.
@@ -162,6 +167,9 @@ struct ProgramDescription {
framebufferMode = SkXfermode::kClear_Mode;
swapSrcDst = false;
+
+ isPoint = false;
+ pointSize = 0.0f;
}
/**
@@ -223,7 +231,8 @@ struct ProgramDescription {
}
key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
- if (modulate) key |= programid(0x1) << PROGRAM_MODULATE;
+ if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
+ if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
return key;
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 1aef99b53f68..2d8b6f3950f6 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -27,8 +27,6 @@
// If turned on, layers drawn inside FBOs are optimized with regions
#define RENDER_LAYERS_AS_REGIONS 1
-// If turned on, layers that map to a single rect are drawn as a rect
-#define RENDER_LAYERS_RECT_AS_RECT 0
/**
* Debug level for app developers.
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index 4c626dd49303..b5cc29c9a691 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -89,14 +89,17 @@ struct ShapeCacheEntry {
join = SkPaint::kDefault_Join;
cap = SkPaint::kDefault_Cap;
style = SkPaint::kFill_Style;
- miter = 4.0f;
- strokeWidth = 1.0f;
+ float v = 4.0f;
+ miter = *(uint32_t*) &v;
+ v = 1.0f;
+ strokeWidth = *(uint32_t*) &v;
+ pathEffect = NULL;
}
ShapeCacheEntry(const ShapeCacheEntry& entry):
shapeType(entry.shapeType), join(entry.join), cap(entry.cap),
style(entry.style), miter(entry.miter),
- strokeWidth(entry.strokeWidth) {
+ strokeWidth(entry.strokeWidth), pathEffect(entry.pathEffect) {
}
ShapeCacheEntry(ShapeType type, SkPaint* paint) {
@@ -108,18 +111,19 @@ struct ShapeCacheEntry {
v = paint->getStrokeWidth();
strokeWidth = *(uint32_t*) &v;
style = paint->getStyle();
+ pathEffect = paint->getPathEffect();
}
virtual ~ShapeCacheEntry() {
}
- // shapeType must be checked in subclasses operator<
ShapeType shapeType;
SkPaint::Join join;
SkPaint::Cap cap;
SkPaint::Style style;
uint32_t miter;
uint32_t strokeWidth;
+ SkPathEffect* pathEffect;
bool operator<(const ShapeCacheEntry& rhs) const {
LTE_INT(shapeType) {
@@ -128,7 +132,9 @@ struct ShapeCacheEntry {
LTE_INT(style) {
LTE_INT(miter) {
LTE_INT(strokeWidth) {
- return lessThan(rhs);
+ LTE_INT(pathEffect) {
+ return lessThan(rhs);
+ }
}
}
}
diff --git a/libs/hwui/utils/GenerationCache.h b/libs/hwui/utils/GenerationCache.h
deleted file mode 100644
index 42e6d9bb8cda..000000000000
--- a/libs/hwui/utils/GenerationCache.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_HWUI_GENERATION_CACHE_H
-#define ANDROID_HWUI_GENERATION_CACHE_H
-
-#include <utils/KeyedVector.h>
-#include <utils/RefBase.h>
-
-namespace android {
-namespace uirenderer {
-
-template<typename EntryKey, typename EntryValue>
-class OnEntryRemoved {
-public:
- virtual ~OnEntryRemoved() { };
- virtual void operator()(EntryKey& key, EntryValue& value) = 0;
-}; // class OnEntryRemoved
-
-template<typename EntryKey, typename EntryValue>
-struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > {
- Entry() { }
- Entry(const Entry<EntryKey, EntryValue>& e):
- key(e.key), value(e.value), parent(e.parent), child(e.child) { }
- Entry(sp<Entry<EntryKey, EntryValue> > e):
- key(e->key), value(e->value), parent(e->parent), child(e->child) { }
-
- EntryKey key;
- EntryValue value;
-
- sp<Entry<EntryKey, EntryValue> > parent;
- sp<Entry<EntryKey, EntryValue> > child;
-}; // struct Entry
-
-template<typename K, typename V>
-class GenerationCache {
-public:
- GenerationCache(uint32_t maxCapacity);
- virtual ~GenerationCache();
-
- enum Capacity {
- kUnlimitedCapacity,
- };
-
- void setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener);
-
- void clear();
-
- bool contains(K key) const;
- V get(K key);
- K getKeyAt(uint32_t index) const;
- bool put(K key, V value);
- V remove(K key);
- V removeOldest();
- V getValueAt(uint32_t index) const;
-
- uint32_t size() const;
-
- void addToCache(sp<Entry<K, V> > entry, K key, V value);
- void attachToCache(sp<Entry<K, V> > entry);
- void detachFromCache(sp<Entry<K, V> > entry);
-
- V removeAt(ssize_t index);
-
- KeyedVector<K, sp<Entry<K, V> > > mCache;
- uint32_t mMaxCapacity;
-
- OnEntryRemoved<K, V>* mListener;
-
- sp<Entry<K, V> > mOldest;
- sp<Entry<K, V> > mYoungest;
-}; // class GenerationCache
-
-template<typename K, typename V>
-GenerationCache<K, V>::GenerationCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), mListener(NULL) {
-};
-
-template<typename K, typename V>
-GenerationCache<K, V>::~GenerationCache() {
- clear();
-};
-
-template<typename K, typename V>
-uint32_t GenerationCache<K, V>::size() const {
- return mCache.size();
-}
-
-template<typename K, typename V>
-void GenerationCache<K, V>::setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener) {
- mListener = listener;
-}
-
-template<typename K, typename V>
-void GenerationCache<K, V>::clear() {
- if (mListener) {
- for (uint32_t i = 0; i < mCache.size(); i++) {
- sp<Entry<K, V> > entry = mCache.valueAt(i);
- if (mListener) {
- (*mListener)(entry->key, entry->value);
- }
- }
- }
- mCache.clear();
- mYoungest.clear();
- mOldest.clear();
-}
-
-template<typename K, typename V>
-bool GenerationCache<K, V>::contains(K key) const {
- return mCache.indexOfKey(key) >= 0;
-}
-
-template<typename K, typename V>
-K GenerationCache<K, V>::getKeyAt(uint32_t index) const {
- return mCache.keyAt(index);
-}
-
-template<typename K, typename V>
-V GenerationCache<K, V>::getValueAt(uint32_t index) const {
- return mCache.valueAt(index)->value;
-}
-
-template<typename K, typename V>
-V GenerationCache<K, V>::get(K key) {
- ssize_t index = mCache.indexOfKey(key);
- if (index >= 0) {
- sp<Entry<K, V> > entry = mCache.valueAt(index);
- if (entry.get()) {
- detachFromCache(entry);
- attachToCache(entry);
- return entry->value;
- }
- }
-
- return NULL;
-}
-
-template<typename K, typename V>
-bool GenerationCache<K, V>::put(K key, V value) {
- if (mMaxCapacity != kUnlimitedCapacity && mCache.size() >= mMaxCapacity) {
- removeOldest();
- }
-
- ssize_t index = mCache.indexOfKey(key);
- if (index < 0) {
- sp<Entry<K, V> > entry = new Entry<K, V>;
- addToCache(entry, key, value);
- return true;
- }
-
- return false;
-}
-
-template<typename K, typename V>
-void GenerationCache<K, V>::addToCache(sp<Entry<K, V> > entry, K key, V value) {
- entry->key = key;
- entry->value = value;
- mCache.add(key, entry);
- attachToCache(entry);
-}
-
-template<typename K, typename V>
-V GenerationCache<K, V>::remove(K key) {
- ssize_t index = mCache.indexOfKey(key);
- if (index >= 0) {
- return removeAt(index);
- }
-
- return NULL;
-}
-
-template<typename K, typename V>
-V GenerationCache<K, V>::removeAt(ssize_t index) {
- sp<Entry<K, V> > entry = mCache.valueAt(index);
- if (mListener) {
- (*mListener)(entry->key, entry->value);
- }
- mCache.removeItemsAt(index, 1);
- detachFromCache(entry);
-
- return entry->value;
-}
-
-template<typename K, typename V>
-V GenerationCache<K, V>::removeOldest() {
- if (mOldest.get()) {
- ssize_t index = mCache.indexOfKey(mOldest->key);
- if (index >= 0) {
- return removeAt(index);
- }
- }
-
- return NULL;
-}
-
-template<typename K, typename V>
-void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) {
- if (!mYoungest.get()) {
- mYoungest = mOldest = entry;
- } else {
- entry->parent = mYoungest;
- mYoungest->child = entry;
- mYoungest = entry;
- }
-}
-
-template<typename K, typename V>
-void GenerationCache<K, V>::detachFromCache(sp<Entry<K, V> > entry) {
- if (entry->parent.get()) {
- entry->parent->child = entry->child;
- }
-
- if (entry->child.get()) {
- entry->child->parent = entry->parent;
- }
-
- if (mOldest == entry) {
- mOldest = entry->child;
- }
-
- if (mYoungest == entry) {
- mYoungest = entry->parent;
- }
-
- entry->parent.clear();
- entry->child.clear();
-}
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_GENERATION_CACHE_H
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 083688771dac..14152d865946 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -28,7 +28,6 @@ RSG_GENERATOR:=$(LOCAL_BUILT_MODULE)
# slangdata_output_var_name := rs_runtime_lib_bc
# LOCAL_MODULE := librslib_rt
-# LOCAL_PRELINK_MODULE := false
# LOCAL_MODULE_CLASS := STATIC_LIBRARIES
# LOCAL_MODULE_TAGS := optional
@@ -114,7 +113,9 @@ LOCAL_SRC_FILES:= \
rsStream.cpp \
rsThreadIO.cpp \
rsType.cpp \
- rsVertexArray.cpp
+ rsVertexArray.cpp \
+ driver/rsdBcc.cpp \
+ driver/rsdCore.cpp
LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index ffa9a8c8b74b..cb6d7e05ebdb 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -24,52 +24,7 @@
extern "C" {
#endif
-//////////////////////////////////////////////////////
-//
-
-typedef void * RsAsyncVoidPtr;
-
-typedef void * RsAdapter1D;
-typedef void * RsAdapter2D;
-typedef void * RsAllocation;
-typedef void * RsAnimation;
-typedef void * RsContext;
-typedef void * RsDevice;
-typedef void * RsElement;
-typedef void * RsFile;
-typedef void * RsFont;
-typedef void * RsSampler;
-typedef void * RsScript;
-typedef void * RsMesh;
-typedef void * RsType;
-typedef void * RsObjectBase;
-
-typedef void * RsProgram;
-typedef void * RsProgramVertex;
-typedef void * RsProgramFragment;
-typedef void * RsProgramStore;
-typedef void * RsProgramRaster;
-
-typedef void (* RsBitmapCallback_t)(void *);
-
-enum RsDeviceParam {
- RS_DEVICE_PARAM_FORCE_SOFTWARE_GL,
- RS_DEVICE_PARAM_COUNT
-};
-
-typedef struct {
- uint32_t colorMin;
- uint32_t colorPref;
- uint32_t alphaMin;
- uint32_t alphaPref;
- uint32_t depthMin;
- uint32_t depthPref;
- uint32_t stencilMin;
- uint32_t stencilPref;
- uint32_t samplesMin;
- uint32_t samplesPref;
- float samplesQ;
-} RsSurfaceConfig;
+#include "RenderScriptDefines.h"
RsDevice rsDeviceCreate();
void rsDeviceDestroy(RsDevice);
@@ -80,258 +35,12 @@ RsContext rsContextCreateGL(RsDevice, uint32_t version,
RsSurfaceConfig sc, uint32_t dpi);
void rsContextDestroy(RsContext);
-enum RsMessageToClientType {
- RS_MESSAGE_TO_CLIENT_NONE = 0,
- RS_MESSAGE_TO_CLIENT_EXCEPTION = 1,
- RS_MESSAGE_TO_CLIENT_RESIZE = 2,
- RS_MESSAGE_TO_CLIENT_ERROR = 3,
- RS_MESSAGE_TO_CLIENT_USER = 4
-};
-
RsMessageToClientType rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait);
RsMessageToClientType rsContextPeekMessage(RsContext vrsc, size_t *receiveLen, uint32_t *subID, bool wait);
void rsContextInitToClient(RsContext);
void rsContextDeinitToClient(RsContext);
-#define RS_MAX_TEXTURE 2
-#define RS_MAX_ATTRIBS 16
-
-
-enum RsAllocationUsageType {
- RS_ALLOCATION_USAGE_SCRIPT = 0x0001,
- RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE = 0x0002,
- RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
- RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
-
- RS_ALLOCATION_USAGE_ALL = 0x000F
-};
-
-enum RsAllocationMipmapControl {
- RS_ALLOCATION_MIPMAP_NONE = 0,
- RS_ALLOCATION_MIPMAP_FULL = 1,
- RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE = 2
-};
-
-enum RsAllocationCubemapFace {
- RS_ALLOCATION_CUBMAP_FACE_POSITVE_X = 0,
- RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_X = 1,
- RS_ALLOCATION_CUBMAP_FACE_POSITVE_Y = 2,
- RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Y = 3,
- RS_ALLOCATION_CUBMAP_FACE_POSITVE_Z = 4,
- RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Z = 5
-};
-
-enum RsDataType {
- RS_TYPE_NONE,
- RS_TYPE_FLOAT_16,
- RS_TYPE_FLOAT_32,
- RS_TYPE_FLOAT_64,
- RS_TYPE_SIGNED_8,
- RS_TYPE_SIGNED_16,
- RS_TYPE_SIGNED_32,
- RS_TYPE_SIGNED_64,
- RS_TYPE_UNSIGNED_8,
- RS_TYPE_UNSIGNED_16,
- RS_TYPE_UNSIGNED_32,
- RS_TYPE_UNSIGNED_64,
-
- RS_TYPE_BOOLEAN,
-
- RS_TYPE_UNSIGNED_5_6_5,
- RS_TYPE_UNSIGNED_5_5_5_1,
- RS_TYPE_UNSIGNED_4_4_4_4,
-
- RS_TYPE_MATRIX_4X4,
- RS_TYPE_MATRIX_3X3,
- RS_TYPE_MATRIX_2X2,
-
- RS_TYPE_ELEMENT = 1000,
- RS_TYPE_TYPE,
- RS_TYPE_ALLOCATION,
- RS_TYPE_SAMPLER,
- RS_TYPE_SCRIPT,
- RS_TYPE_MESH,
- RS_TYPE_PROGRAM_FRAGMENT,
- RS_TYPE_PROGRAM_VERTEX,
- RS_TYPE_PROGRAM_RASTER,
- RS_TYPE_PROGRAM_STORE,
-};
-
-enum RsDataKind {
- RS_KIND_USER,
-
- RS_KIND_PIXEL_L = 7,
- RS_KIND_PIXEL_A,
- RS_KIND_PIXEL_LA,
- RS_KIND_PIXEL_RGB,
- RS_KIND_PIXEL_RGBA,
-};
-
-enum RsSamplerParam {
- RS_SAMPLER_MIN_FILTER,
- RS_SAMPLER_MAG_FILTER,
- RS_SAMPLER_WRAP_S,
- RS_SAMPLER_WRAP_T,
- RS_SAMPLER_WRAP_R,
- RS_SAMPLER_ANISO
-};
-
-enum RsSamplerValue {
- RS_SAMPLER_NEAREST,
- RS_SAMPLER_LINEAR,
- RS_SAMPLER_LINEAR_MIP_LINEAR,
- RS_SAMPLER_WRAP,
- RS_SAMPLER_CLAMP,
- RS_SAMPLER_LINEAR_MIP_NEAREST,
-};
-
-enum RsTextureTarget {
- RS_TEXTURE_2D,
- RS_TEXTURE_CUBE
-};
-
-enum RsDimension {
- RS_DIMENSION_X,
- RS_DIMENSION_Y,
- RS_DIMENSION_Z,
- RS_DIMENSION_LOD,
- RS_DIMENSION_FACE,
-
- RS_DIMENSION_ARRAY_0 = 100,
- RS_DIMENSION_ARRAY_1,
- RS_DIMENSION_ARRAY_2,
- RS_DIMENSION_ARRAY_3,
- RS_DIMENSION_MAX = RS_DIMENSION_ARRAY_3
-};
-
-enum RsDepthFunc {
- RS_DEPTH_FUNC_ALWAYS,
- RS_DEPTH_FUNC_LESS,
- RS_DEPTH_FUNC_LEQUAL,
- RS_DEPTH_FUNC_GREATER,
- RS_DEPTH_FUNC_GEQUAL,
- RS_DEPTH_FUNC_EQUAL,
- RS_DEPTH_FUNC_NOTEQUAL
-};
-
-enum RsBlendSrcFunc {
- RS_BLEND_SRC_ZERO, // 0
- RS_BLEND_SRC_ONE, // 1
- RS_BLEND_SRC_DST_COLOR, // 2
- RS_BLEND_SRC_ONE_MINUS_DST_COLOR, // 3
- RS_BLEND_SRC_SRC_ALPHA, // 4
- RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, // 5
- RS_BLEND_SRC_DST_ALPHA, // 6
- RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, // 7
- RS_BLEND_SRC_SRC_ALPHA_SATURATE // 8
-};
-
-enum RsBlendDstFunc {
- RS_BLEND_DST_ZERO, // 0
- RS_BLEND_DST_ONE, // 1
- RS_BLEND_DST_SRC_COLOR, // 2
- RS_BLEND_DST_ONE_MINUS_SRC_COLOR, // 3
- RS_BLEND_DST_SRC_ALPHA, // 4
- RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, // 5
- RS_BLEND_DST_DST_ALPHA, // 6
- RS_BLEND_DST_ONE_MINUS_DST_ALPHA // 7
-};
-
-enum RsTexEnvMode {
- RS_TEX_ENV_MODE_NONE,
- RS_TEX_ENV_MODE_REPLACE,
- RS_TEX_ENV_MODE_MODULATE,
- RS_TEX_ENV_MODE_DECAL
-};
-
-enum RsProgramParam {
- RS_PROGRAM_PARAM_INPUT,
- RS_PROGRAM_PARAM_OUTPUT,
- RS_PROGRAM_PARAM_CONSTANT,
- RS_PROGRAM_PARAM_TEXTURE_TYPE,
-};
-
-enum RsPrimitive {
- RS_PRIMITIVE_POINT,
- RS_PRIMITIVE_LINE,
- RS_PRIMITIVE_LINE_STRIP,
- RS_PRIMITIVE_TRIANGLE,
- RS_PRIMITIVE_TRIANGLE_STRIP,
- RS_PRIMITIVE_TRIANGLE_FAN
-};
-
-enum RsError {
- RS_ERROR_NONE = 0,
- RS_ERROR_BAD_SHADER = 1,
- RS_ERROR_BAD_SCRIPT = 2,
- RS_ERROR_BAD_VALUE = 3,
- RS_ERROR_OUT_OF_MEMORY = 4,
- RS_ERROR_DRIVER = 5,
-
- RS_ERROR_FATAL_UNKNOWN = 0x1000,
- RS_ERROR_FATAL_DRIVER = 0x1001,
- RS_ERROR_FATAL_PROGRAM_LINK = 0x1002
-};
-
-enum RsAnimationInterpolation {
- RS_ANIMATION_INTERPOLATION_STEP,
- RS_ANIMATION_INTERPOLATION_LINEAR,
- RS_ANIMATION_INTERPOLATION_BEZIER,
- RS_ANIMATION_INTERPOLATION_CARDINAL,
- RS_ANIMATION_INTERPOLATION_HERMITE,
- RS_ANIMATION_INTERPOLATION_BSPLINE
-};
-
-enum RsAnimationEdge {
- RS_ANIMATION_EDGE_UNDEFINED,
- RS_ANIMATION_EDGE_CONSTANT,
- RS_ANIMATION_EDGE_GRADIENT,
- RS_ANIMATION_EDGE_CYCLE,
- RS_ANIMATION_EDGE_OSCILLATE,
- RS_ANIMATION_EDGE_CYLE_RELATIVE
-};
-
-enum RsA3DClassID {
- RS_A3D_CLASS_ID_UNKNOWN,
- RS_A3D_CLASS_ID_MESH,
- RS_A3D_CLASS_ID_TYPE,
- RS_A3D_CLASS_ID_ELEMENT,
- RS_A3D_CLASS_ID_ALLOCATION,
- RS_A3D_CLASS_ID_PROGRAM_VERTEX,
- RS_A3D_CLASS_ID_PROGRAM_RASTER,
- RS_A3D_CLASS_ID_PROGRAM_FRAGMENT,
- RS_A3D_CLASS_ID_PROGRAM_STORE,
- RS_A3D_CLASS_ID_SAMPLER,
- RS_A3D_CLASS_ID_ANIMATION,
- RS_A3D_CLASS_ID_ADAPTER_1D,
- RS_A3D_CLASS_ID_ADAPTER_2D,
- RS_A3D_CLASS_ID_SCRIPT_C
-};
-
-enum RsCullMode {
- RS_CULL_BACK,
- RS_CULL_FRONT,
- RS_CULL_NONE
-};
-
-typedef struct {
- RsA3DClassID classID;
- const char* objectName;
-} RsFileIndexEntry;
-
-// Script to Script
-typedef struct {
- uint32_t xStart;
- uint32_t xEnd;
- uint32_t yStart;
- uint32_t yEnd;
- uint32_t zStart;
- uint32_t zEnd;
- uint32_t arrayStart;
- uint32_t arrayEnd;
-
-} RsScriptCall;
-
+//
// A3D loading and object update code.
// Should only be called at object creation, not thread safe
RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile);
diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/RenderScriptDefines.h
new file mode 100644
index 000000000000..4e1ac88094dd
--- /dev/null
+++ b/libs/rs/RenderScriptDefines.h
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+#ifndef RENDER_SCRIPT_DEFINES_H
+#define RENDER_SCRIPT_DEFINES_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//////////////////////////////////////////////////////
+//
+
+typedef void * RsAsyncVoidPtr;
+
+typedef void * RsAdapter1D;
+typedef void * RsAdapter2D;
+typedef void * RsAllocation;
+typedef void * RsAnimation;
+typedef void * RsContext;
+typedef void * RsDevice;
+typedef void * RsElement;
+typedef void * RsFile;
+typedef void * RsFont;
+typedef void * RsSampler;
+typedef void * RsScript;
+typedef void * RsMesh;
+typedef void * RsType;
+typedef void * RsObjectBase;
+
+typedef void * RsProgram;
+typedef void * RsProgramVertex;
+typedef void * RsProgramFragment;
+typedef void * RsProgramStore;
+typedef void * RsProgramRaster;
+
+typedef void (* RsBitmapCallback_t)(void *);
+
+enum RsDeviceParam {
+ RS_DEVICE_PARAM_FORCE_SOFTWARE_GL,
+ RS_DEVICE_PARAM_COUNT
+};
+
+typedef struct {
+ uint32_t colorMin;
+ uint32_t colorPref;
+ uint32_t alphaMin;
+ uint32_t alphaPref;
+ uint32_t depthMin;
+ uint32_t depthPref;
+ uint32_t stencilMin;
+ uint32_t stencilPref;
+ uint32_t samplesMin;
+ uint32_t samplesPref;
+ float samplesQ;
+} RsSurfaceConfig;
+
+enum RsMessageToClientType {
+ RS_MESSAGE_TO_CLIENT_NONE = 0,
+ RS_MESSAGE_TO_CLIENT_EXCEPTION = 1,
+ RS_MESSAGE_TO_CLIENT_RESIZE = 2,
+ RS_MESSAGE_TO_CLIENT_ERROR = 3,
+ RS_MESSAGE_TO_CLIENT_USER = 4
+};
+
+enum RsAllocationUsageType {
+ RS_ALLOCATION_USAGE_SCRIPT = 0x0001,
+ RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE = 0x0002,
+ RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
+ RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
+
+ RS_ALLOCATION_USAGE_ALL = 0x000F
+};
+
+enum RsAllocationMipmapControl {
+ RS_ALLOCATION_MIPMAP_NONE = 0,
+ RS_ALLOCATION_MIPMAP_FULL = 1,
+ RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE = 2
+};
+
+enum RsAllocationCubemapFace {
+ RS_ALLOCATION_CUBMAP_FACE_POSITVE_X = 0,
+ RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_X = 1,
+ RS_ALLOCATION_CUBMAP_FACE_POSITVE_Y = 2,
+ RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Y = 3,
+ RS_ALLOCATION_CUBMAP_FACE_POSITVE_Z = 4,
+ RS_ALLOCATION_CUBMAP_FACE_NEGATIVE_Z = 5
+};
+
+enum RsDataType {
+ RS_TYPE_NONE,
+ RS_TYPE_FLOAT_16,
+ RS_TYPE_FLOAT_32,
+ RS_TYPE_FLOAT_64,
+ RS_TYPE_SIGNED_8,
+ RS_TYPE_SIGNED_16,
+ RS_TYPE_SIGNED_32,
+ RS_TYPE_SIGNED_64,
+ RS_TYPE_UNSIGNED_8,
+ RS_TYPE_UNSIGNED_16,
+ RS_TYPE_UNSIGNED_32,
+ RS_TYPE_UNSIGNED_64,
+
+ RS_TYPE_BOOLEAN,
+
+ RS_TYPE_UNSIGNED_5_6_5,
+ RS_TYPE_UNSIGNED_5_5_5_1,
+ RS_TYPE_UNSIGNED_4_4_4_4,
+
+ RS_TYPE_MATRIX_4X4,
+ RS_TYPE_MATRIX_3X3,
+ RS_TYPE_MATRIX_2X2,
+
+ RS_TYPE_ELEMENT = 1000,
+ RS_TYPE_TYPE,
+ RS_TYPE_ALLOCATION,
+ RS_TYPE_SAMPLER,
+ RS_TYPE_SCRIPT,
+ RS_TYPE_MESH,
+ RS_TYPE_PROGRAM_FRAGMENT,
+ RS_TYPE_PROGRAM_VERTEX,
+ RS_TYPE_PROGRAM_RASTER,
+ RS_TYPE_PROGRAM_STORE,
+};
+
+enum RsDataKind {
+ RS_KIND_USER,
+
+ RS_KIND_PIXEL_L = 7,
+ RS_KIND_PIXEL_A,
+ RS_KIND_PIXEL_LA,
+ RS_KIND_PIXEL_RGB,
+ RS_KIND_PIXEL_RGBA,
+};
+
+enum RsSamplerParam {
+ RS_SAMPLER_MIN_FILTER,
+ RS_SAMPLER_MAG_FILTER,
+ RS_SAMPLER_WRAP_S,
+ RS_SAMPLER_WRAP_T,
+ RS_SAMPLER_WRAP_R,
+ RS_SAMPLER_ANISO
+};
+
+enum RsSamplerValue {
+ RS_SAMPLER_NEAREST,
+ RS_SAMPLER_LINEAR,
+ RS_SAMPLER_LINEAR_MIP_LINEAR,
+ RS_SAMPLER_WRAP,
+ RS_SAMPLER_CLAMP,
+ RS_SAMPLER_LINEAR_MIP_NEAREST,
+};
+
+enum RsTextureTarget {
+ RS_TEXTURE_2D,
+ RS_TEXTURE_CUBE
+};
+
+enum RsDimension {
+ RS_DIMENSION_X,
+ RS_DIMENSION_Y,
+ RS_DIMENSION_Z,
+ RS_DIMENSION_LOD,
+ RS_DIMENSION_FACE,
+
+ RS_DIMENSION_ARRAY_0 = 100,
+ RS_DIMENSION_ARRAY_1,
+ RS_DIMENSION_ARRAY_2,
+ RS_DIMENSION_ARRAY_3,
+ RS_DIMENSION_MAX = RS_DIMENSION_ARRAY_3
+};
+
+enum RsDepthFunc {
+ RS_DEPTH_FUNC_ALWAYS,
+ RS_DEPTH_FUNC_LESS,
+ RS_DEPTH_FUNC_LEQUAL,
+ RS_DEPTH_FUNC_GREATER,
+ RS_DEPTH_FUNC_GEQUAL,
+ RS_DEPTH_FUNC_EQUAL,
+ RS_DEPTH_FUNC_NOTEQUAL
+};
+
+enum RsBlendSrcFunc {
+ RS_BLEND_SRC_ZERO, // 0
+ RS_BLEND_SRC_ONE, // 1
+ RS_BLEND_SRC_DST_COLOR, // 2
+ RS_BLEND_SRC_ONE_MINUS_DST_COLOR, // 3
+ RS_BLEND_SRC_SRC_ALPHA, // 4
+ RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_SRC_DST_ALPHA, // 6
+ RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, // 7
+ RS_BLEND_SRC_SRC_ALPHA_SATURATE // 8
+};
+
+enum RsBlendDstFunc {
+ RS_BLEND_DST_ZERO, // 0
+ RS_BLEND_DST_ONE, // 1
+ RS_BLEND_DST_SRC_COLOR, // 2
+ RS_BLEND_DST_ONE_MINUS_SRC_COLOR, // 3
+ RS_BLEND_DST_SRC_ALPHA, // 4
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_DST_DST_ALPHA, // 6
+ RS_BLEND_DST_ONE_MINUS_DST_ALPHA // 7
+};
+
+enum RsTexEnvMode {
+ RS_TEX_ENV_MODE_NONE,
+ RS_TEX_ENV_MODE_REPLACE,
+ RS_TEX_ENV_MODE_MODULATE,
+ RS_TEX_ENV_MODE_DECAL
+};
+
+enum RsProgramParam {
+ RS_PROGRAM_PARAM_INPUT,
+ RS_PROGRAM_PARAM_OUTPUT,
+ RS_PROGRAM_PARAM_CONSTANT,
+ RS_PROGRAM_PARAM_TEXTURE_TYPE,
+};
+
+enum RsPrimitive {
+ RS_PRIMITIVE_POINT,
+ RS_PRIMITIVE_LINE,
+ RS_PRIMITIVE_LINE_STRIP,
+ RS_PRIMITIVE_TRIANGLE,
+ RS_PRIMITIVE_TRIANGLE_STRIP,
+ RS_PRIMITIVE_TRIANGLE_FAN
+};
+
+enum RsError {
+ RS_ERROR_NONE = 0,
+ RS_ERROR_BAD_SHADER = 1,
+ RS_ERROR_BAD_SCRIPT = 2,
+ RS_ERROR_BAD_VALUE = 3,
+ RS_ERROR_OUT_OF_MEMORY = 4,
+ RS_ERROR_DRIVER = 5,
+
+ RS_ERROR_FATAL_UNKNOWN = 0x1000,
+ RS_ERROR_FATAL_DRIVER = 0x1001,
+ RS_ERROR_FATAL_PROGRAM_LINK = 0x1002
+};
+
+enum RsAnimationInterpolation {
+ RS_ANIMATION_INTERPOLATION_STEP,
+ RS_ANIMATION_INTERPOLATION_LINEAR,
+ RS_ANIMATION_INTERPOLATION_BEZIER,
+ RS_ANIMATION_INTERPOLATION_CARDINAL,
+ RS_ANIMATION_INTERPOLATION_HERMITE,
+ RS_ANIMATION_INTERPOLATION_BSPLINE
+};
+
+enum RsAnimationEdge {
+ RS_ANIMATION_EDGE_UNDEFINED,
+ RS_ANIMATION_EDGE_CONSTANT,
+ RS_ANIMATION_EDGE_GRADIENT,
+ RS_ANIMATION_EDGE_CYCLE,
+ RS_ANIMATION_EDGE_OSCILLATE,
+ RS_ANIMATION_EDGE_CYLE_RELATIVE
+};
+
+enum RsA3DClassID {
+ RS_A3D_CLASS_ID_UNKNOWN,
+ RS_A3D_CLASS_ID_MESH,
+ RS_A3D_CLASS_ID_TYPE,
+ RS_A3D_CLASS_ID_ELEMENT,
+ RS_A3D_CLASS_ID_ALLOCATION,
+ RS_A3D_CLASS_ID_PROGRAM_VERTEX,
+ RS_A3D_CLASS_ID_PROGRAM_RASTER,
+ RS_A3D_CLASS_ID_PROGRAM_FRAGMENT,
+ RS_A3D_CLASS_ID_PROGRAM_STORE,
+ RS_A3D_CLASS_ID_SAMPLER,
+ RS_A3D_CLASS_ID_ANIMATION,
+ RS_A3D_CLASS_ID_ADAPTER_1D,
+ RS_A3D_CLASS_ID_ADAPTER_2D,
+ RS_A3D_CLASS_ID_SCRIPT_C
+};
+
+enum RsCullMode {
+ RS_CULL_BACK,
+ RS_CULL_FRONT,
+ RS_CULL_NONE
+};
+
+typedef struct {
+ RsA3DClassID classID;
+ const char* objectName;
+} RsFileIndexEntry;
+
+// Script to Script
+typedef struct {
+ uint32_t xStart;
+ uint32_t xEnd;
+ uint32_t yStart;
+ uint32_t yEnd;
+ uint32_t zStart;
+ uint32_t zEnd;
+ uint32_t arrayStart;
+ uint32_t arrayEnd;
+
+} RsScriptCall;
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif // RENDER_SCRIPT_DEFINES_H
+
+
+
+
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
new file mode 100644
index 000000000000..6c5a55be85ed
--- /dev/null
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "rsdCore.h"
+#include "rsdBcc.h"
+
+#include "rsContext.h"
+#include "rsScriptC.h"
+
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+extern "C" {
+#include "libdex/ZipArchive.h"
+}
+
+
+using namespace android;
+using namespace android::renderscript;
+
+struct DrvScript {
+ int (*mRoot)();
+ void (*mInit)();
+
+ BCCScriptRef mBccScript;
+
+ uint32_t mInvokeFunctionCount;
+ InvokeFunc_t *mInvokeFunctions;
+ uint32_t mFieldCount;
+ void ** mFieldAddress;
+ bool * mFieldIsObject;
+
+ const uint8_t * mScriptText;
+ uint32_t mScriptTextLength;
+
+ //uint32_t * mObjectSlots;
+ //uint32_t mObjectSlotCount;
+
+ uint32_t mPragmaCount;
+ const char ** mPragmaKeys;
+ const char ** mPragmaValues;
+
+};
+
+static Script * setTLS(Script *sc) {
+ ScriptTLSStruct * tls = (ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
+ rsAssert(tls);
+ Script *old = tls->mScript;
+ tls->mScript = sc;
+ return old;
+}
+
+
+// Input: cacheDir
+// Input: resName
+// Input: extName
+//
+// Note: cacheFile = resName + extName
+//
+// Output: Returns cachePath == cacheDir + cacheFile
+static char *genCacheFileName(const char *cacheDir,
+ const char *resName,
+ const char *extName) {
+ char cachePath[512];
+ char cacheFile[sizeof(cachePath)];
+ const size_t kBufLen = sizeof(cachePath) - 1;
+
+ cacheFile[0] = '\0';
+ // Note: resName today is usually something like
+ // "/com.android.fountain:raw/fountain"
+ if (resName[0] != '/') {
+ // Get the absolute path of the raw/***.bc file.
+
+ // Generate the absolute path. This doesn't do everything it
+ // should, e.g. if resName is "./out/whatever" it doesn't crunch
+ // the leading "./" out because this if-block is not triggered,
+ // but it'll make do.
+ //
+ if (getcwd(cacheFile, kBufLen) == NULL) {
+ LOGE("Can't get CWD while opening raw/***.bc file\n");
+ return NULL;
+ }
+ // Append "/" at the end of cacheFile so far.
+ strncat(cacheFile, "/", kBufLen);
+ }
+
+ // cacheFile = resName + extName
+ //
+ strncat(cacheFile, resName, kBufLen);
+ if (extName != NULL) {
+ // TODO(srhines): strncat() is a bit dangerous
+ strncat(cacheFile, extName, kBufLen);
+ }
+
+ // Turn the path into a flat filename by replacing
+ // any slashes after the first one with '@' characters.
+ char *cp = cacheFile + 1;
+ while (*cp != '\0') {
+ if (*cp == '/') {
+ *cp = '@';
+ }
+ cp++;
+ }
+
+ // Tack on the file name for the actual cache file path.
+ strncpy(cachePath, cacheDir, kBufLen);
+ strncat(cachePath, cacheFile, kBufLen);
+
+ LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
+ return strdup(cachePath);
+}
+
+bool rsdScriptInit(const Context *rsc,
+ ScriptC *script,
+ char const *resName,
+ char const *cacheDir,
+ uint8_t const *bitcode,
+ size_t bitcodeSize,
+ uint32_t flags,
+ RsHalSymbolLookupFunc lookupFunc) {
+ //LOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
+
+ char *cachePath = NULL;
+ uint32_t objectSlotCount = 0;
+
+ DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
+ if (drv == NULL) {
+ return false;
+ }
+ script->mHal.drv = drv;
+
+ drv->mBccScript = bccCreateScript();
+ script->mHal.info.isThreadable = true;
+ drv->mScriptText = bitcode;
+ drv->mScriptTextLength = bitcodeSize;
+
+ //LOGE("mBccScript %p", script->mBccScript);
+
+ if (bccRegisterSymbolCallback(drv->mBccScript, lookupFunc, script) != 0) {
+ LOGE("bcc: FAILS to register symbol callback");
+ goto error;
+ }
+
+ if (bccReadBC(drv->mBccScript,
+ resName,
+ (char const *)drv->mScriptText,
+ drv->mScriptTextLength, 0) != 0) {
+ LOGE("bcc: FAILS to read bitcode");
+ return NULL;
+ }
+
+#if 1
+ if (bccLinkFile(drv->mBccScript, "/system/lib/libclcore.bc", 0) != 0) {
+ LOGE("bcc: FAILS to link bitcode");
+ return NULL;
+ }
+#endif
+ cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
+
+ if (bccPrepareExecutable(drv->mBccScript, cachePath, 0) != 0) {
+ LOGE("bcc: FAILS to prepare executable");
+ return NULL;
+ }
+
+ free(cachePath);
+
+ drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
+ drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
+
+ drv->mInvokeFunctionCount = bccGetExportFuncCount(drv->mBccScript);
+ if (drv->mInvokeFunctionCount <= 0)
+ drv->mInvokeFunctions = NULL;
+ else {
+ drv->mInvokeFunctions = (InvokeFunc_t*) calloc(drv->mInvokeFunctionCount, sizeof(InvokeFunc_t));
+ bccGetExportFuncList(drv->mBccScript, drv->mInvokeFunctionCount, (void **) drv->mInvokeFunctions);
+ }
+
+ drv->mFieldCount = bccGetExportVarCount(drv->mBccScript);
+ if (drv->mFieldCount <= 0) {
+ drv->mFieldAddress = NULL;
+ drv->mFieldIsObject = NULL;
+ } else {
+ drv->mFieldAddress = (void **) calloc(drv->mFieldCount, sizeof(void *));
+ drv->mFieldIsObject = (bool *) calloc(drv->mFieldCount, sizeof(bool));
+ bccGetExportVarList(drv->mBccScript, drv->mFieldCount, (void **) drv->mFieldAddress);
+ }
+
+ objectSlotCount = bccGetObjectSlotCount(drv->mBccScript);
+ if (objectSlotCount) {
+ uint32_t * slots = new uint32_t[objectSlotCount];
+ bccGetObjectSlotList(drv->mBccScript, objectSlotCount, slots);
+ for (uint32_t ct=0; ct < objectSlotCount; ct++) {
+ drv->mFieldIsObject[slots[ct]] = true;
+ }
+ delete [] slots;
+ }
+
+ uint32_t mPragmaCount;
+ const char ** mPragmaKeys;
+ const char ** mPragmaValues;
+
+ const static int pragmaMax = 16;
+ drv->mPragmaCount = bccGetPragmaCount(drv->mBccScript);
+ if (drv->mPragmaCount <= 0) {
+ drv->mPragmaKeys = NULL;
+ drv->mPragmaValues = NULL;
+ } else {
+ drv->mPragmaKeys = (const char **) calloc(drv->mFieldCount, sizeof(const char *));
+ drv->mPragmaValues = (const char **) calloc(drv->mFieldCount, sizeof(const char *));
+ bccGetPragmaList(drv->mBccScript, drv->mPragmaCount, drv->mPragmaKeys, drv->mPragmaValues);
+ }
+
+
+
+ // Copy info over to runtime
+ script->mHal.info.exportedFunctionCount = drv->mInvokeFunctionCount;
+ script->mHal.info.exportedVariableCount = drv->mFieldCount;
+ script->mHal.info.exportedPragmaCount = drv->mPragmaCount;
+ script->mHal.info.exportedPragmaKeyList = drv->mPragmaKeys;
+ script->mHal.info.exportedPragmaValueList = drv->mPragmaValues;
+ script->mHal.info.root = drv->mRoot;
+
+
+ return true;
+
+error:
+
+ free(drv);
+ return false;
+
+}
+
+typedef struct {
+ Context *rsc;
+ Script *script;
+ const Allocation * ain;
+ Allocation * aout;
+ const void * usr;
+
+ uint32_t mSliceSize;
+ volatile int mSliceNum;
+
+ const uint8_t *ptrIn;
+ uint32_t eStrideIn;
+ uint8_t *ptrOut;
+ uint32_t eStrideOut;
+
+ uint32_t xStart;
+ uint32_t xEnd;
+ uint32_t yStart;
+ uint32_t yEnd;
+ uint32_t zStart;
+ uint32_t zEnd;
+ uint32_t arrayStart;
+ uint32_t arrayEnd;
+
+ uint32_t dimX;
+ uint32_t dimY;
+ uint32_t dimZ;
+ uint32_t dimArray;
+} MTLaunchStruct;
+typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
+
+static void wc_xy(void *usr, uint32_t idx) {
+ MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+
+ while (1) {
+ uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
+ uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
+ uint32_t yEnd = yStart + mtls->mSliceSize;
+ yEnd = rsMin(yEnd, mtls->yEnd);
+ if (yEnd <= yStart) {
+ return;
+ }
+
+ //LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
+ //LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
+ for (uint32_t y = yStart; y < yEnd; y++) {
+ uint32_t offset = mtls->dimX * y;
+ uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
+ const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
+
+ for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) {
+ ((rs_t)mtls->script->mHal.info.root) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0);
+ xPtrIn += mtls->eStrideIn;
+ xPtrOut += mtls->eStrideOut;
+ }
+ }
+ }
+}
+
+static void wc_x(void *usr, uint32_t idx) {
+ MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+
+ while (1) {
+ uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
+ uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
+ uint32_t xEnd = xStart + mtls->mSliceSize;
+ xEnd = rsMin(xEnd, mtls->xEnd);
+ if (xEnd <= xStart) {
+ return;
+ }
+
+ //LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
+ //LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
+ uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * xStart);
+ const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * xStart);
+ for (uint32_t x = xStart; x < xEnd; x++) {
+ ((rs_t)mtls->script->mHal.info.root) (xPtrIn, xPtrOut, mtls->usr, x, 0, 0, 0);
+ xPtrIn += mtls->eStrideIn;
+ xPtrOut += mtls->eStrideOut;
+ }
+ }
+}
+
+void rsdScriptInvokeForEach(const Context *rsc,
+ Script *s,
+ const Allocation * ain,
+ Allocation * aout,
+ const void * usr,
+ uint32_t usrLen,
+ const RsScriptCall *sc) {
+
+ RsHal * dc = (RsHal *)rsc->mHal.drv;
+
+ MTLaunchStruct mtls;
+ memset(&mtls, 0, sizeof(mtls));
+
+ if (ain) {
+ mtls.dimX = ain->getType()->getDimX();
+ mtls.dimY = ain->getType()->getDimY();
+ mtls.dimZ = ain->getType()->getDimZ();
+ //mtls.dimArray = ain->getType()->getDimArray();
+ } else if (aout) {
+ mtls.dimX = aout->getType()->getDimX();
+ mtls.dimY = aout->getType()->getDimY();
+ mtls.dimZ = aout->getType()->getDimZ();
+ //mtls.dimArray = aout->getType()->getDimArray();
+ } else {
+ rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
+ return;
+ }
+
+ if (!sc || (sc->xEnd == 0)) {
+ mtls.xEnd = mtls.dimX;
+ } else {
+ rsAssert(sc->xStart < mtls.dimX);
+ rsAssert(sc->xEnd <= mtls.dimX);
+ rsAssert(sc->xStart < sc->xEnd);
+ mtls.xStart = rsMin(mtls.dimX, sc->xStart);
+ mtls.xEnd = rsMin(mtls.dimX, sc->xEnd);
+ if (mtls.xStart >= mtls.xEnd) return;
+ }
+
+ if (!sc || (sc->yEnd == 0)) {
+ mtls.yEnd = mtls.dimY;
+ } else {
+ rsAssert(sc->yStart < mtls.dimY);
+ rsAssert(sc->yEnd <= mtls.dimY);
+ rsAssert(sc->yStart < sc->yEnd);
+ mtls.yStart = rsMin(mtls.dimY, sc->yStart);
+ mtls.yEnd = rsMin(mtls.dimY, sc->yEnd);
+ if (mtls.yStart >= mtls.yEnd) return;
+ }
+
+ mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd);
+ mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd);
+ mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd);
+ mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd);
+
+ rsAssert(ain->getType()->getDimZ() == 0);
+
+ Context *mrsc = (Context *)rsc;
+ Script * oldTLS = setTLS(s);
+
+ mtls.rsc = mrsc;
+ mtls.ain = ain;
+ mtls.aout = aout;
+ mtls.script = s;
+ mtls.usr = usr;
+ mtls.mSliceSize = 10;
+ mtls.mSliceNum = 0;
+
+ mtls.ptrIn = NULL;
+ mtls.eStrideIn = 0;
+ if (ain) {
+ mtls.ptrIn = (const uint8_t *)ain->getPtr();
+ mtls.eStrideIn = ain->getType()->getElementSizeBytes();
+ }
+
+ mtls.ptrOut = NULL;
+ mtls.eStrideOut = 0;
+ if (aout) {
+ mtls.ptrOut = (uint8_t *)aout->getPtr();
+ mtls.eStrideOut = aout->getType()->getElementSizeBytes();
+ }
+
+ if ((dc->mWorkers.mCount > 1) && s->mHal.info.isThreadable) {
+ if (mtls.dimY > 1) {
+ rsdLaunchThreads(mrsc, wc_xy, &mtls);
+ } else {
+ rsdLaunchThreads(mrsc, wc_x, &mtls);
+ }
+
+ //LOGE("launch 1");
+ } else {
+ //LOGE("launch 3");
+ for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) {
+ for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) {
+ for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) {
+ uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar +
+ mtls.dimX * mtls.dimY * z +
+ mtls.dimX * y;
+ uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
+ const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
+
+ for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) {
+ ((rs_t)s->mHal.info.root) (xPtrIn, xPtrOut, usr, x, y, z, ar);
+ xPtrIn += mtls.eStrideIn;
+ xPtrOut += mtls.eStrideOut;
+ }
+ }
+ }
+ }
+ }
+
+ setTLS(oldTLS);
+}
+
+
+int rsdScriptInvokeRoot(const Context *dc, Script *script) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+ Script * oldTLS = setTLS(script);
+ int ret = drv->mRoot();
+ setTLS(oldTLS);
+
+ return ret;
+}
+
+void rsdScriptInvokeInit(const Context *dc, Script *script) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+ if (drv->mInit) {
+ drv->mInit();
+ }
+}
+
+
+void rsdScriptInvokeFunction(const Context *dc, Script *script,
+ uint32_t slot,
+ const void *params,
+ size_t paramLength) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+ //LOGE("invoke %p %p %i %p %i", dc, script, slot, params, paramLength);
+
+ Script * oldTLS = setTLS(script);
+ ((void (*)(const void *, uint32_t))
+ drv->mInvokeFunctions[slot])(params, paramLength);
+ setTLS(oldTLS);
+}
+
+void rsdScriptSetGlobalVar(const Context *dc, const Script *script,
+ uint32_t slot, void *data, size_t dataLength) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+ //rsAssert(!script->mFieldIsObject[slot]);
+ //LOGE("setGlobalVar %p %p %i %p %i", dc, script, slot, data, dataLength);
+
+ int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
+ if (!destPtr) {
+ //LOGV("Calling setVar on slot = %i which is null", slot);
+ return;
+ }
+
+ memcpy(destPtr, data, dataLength);
+}
+
+void rsdScriptSetGlobalBind(const Context *dc, const Script *script, uint32_t slot, void *data) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+ //rsAssert(!script->mFieldIsObject[slot]);
+ //LOGE("setGlobalBind %p %p %i %p", dc, script, slot, data);
+
+ int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
+ if (!destPtr) {
+ //LOGV("Calling setVar on slot = %i which is null", slot);
+ return;
+ }
+
+ memcpy(destPtr, &data, sizeof(void *));
+}
+
+void rsdScriptSetGlobalObj(const Context *dc, const Script *script, uint32_t slot, ObjectBase *data) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+ //rsAssert(script->mFieldIsObject[slot]);
+ //LOGE("setGlobalObj %p %p %i %p", dc, script, slot, data);
+
+ int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
+ if (!destPtr) {
+ //LOGV("Calling setVar on slot = %i which is null", slot);
+ return;
+ }
+
+ rsiSetObject((ObjectBase **)destPtr, data);
+}
+
+void rsdScriptDestroy(const Context *dc, Script *script) {
+ DrvScript *drv = (DrvScript *)script->mHal.drv;
+
+ if (drv->mFieldAddress) {
+ for (size_t ct=0; ct < drv->mFieldCount; ct++) {
+ if (drv->mFieldIsObject[ct]) {
+ // The field address can be NULL if the script-side has
+ // optimized the corresponding global variable away.
+ if (drv->mFieldAddress[ct]) {
+ rsiClearObject((ObjectBase **)drv->mFieldAddress[ct]);
+ }
+ }
+ }
+ delete [] drv->mFieldAddress;
+ delete [] drv->mFieldIsObject;
+ drv->mFieldAddress = NULL;
+ drv->mFieldIsObject = NULL;
+ drv->mFieldCount = 0;
+ }
+
+ if (drv->mInvokeFunctions) {
+ delete [] drv->mInvokeFunctions;
+ drv->mInvokeFunctions = NULL;
+ drv->mInvokeFunctionCount = 0;
+ }
+ free(drv);
+ script->mHal.drv = NULL;
+
+}
+
+
diff --git a/libs/rs/driver/rsdBcc.h b/libs/rs/driver/rsdBcc.h
new file mode 100644
index 000000000000..6723a3640fd0
--- /dev/null
+++ b/libs/rs/driver/rsdBcc.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef RSD_BCC_H
+#define RSD_BCC_H
+
+#include <rs_hal.h>
+
+
+bool rsdScriptInit(const android::renderscript::Context *, android::renderscript::ScriptC *,
+ char const *resName, char const *cacheDir,
+ uint8_t const *bitcode, size_t bitcodeSize,
+ uint32_t flags, android::renderscript::RsHalSymbolLookupFunc lookupFunc);
+void rsdScriptInvokeFunction(const android::renderscript::Context *dc,
+ android::renderscript::Script *script,
+ uint32_t slot,
+ const void *params,
+ size_t paramLength);
+
+void rsdScriptInvokeForEach(const android::renderscript::Context *rsc,
+ android::renderscript::Script *s,
+ const android::renderscript::Allocation * ain,
+ android::renderscript::Allocation * aout,
+ const void * usr,
+ uint32_t usrLen,
+ const RsScriptCall *sc);
+
+int rsdScriptInvokeRoot(const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+void rsdScriptInvokeInit(const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+
+void rsdScriptSetGlobalVar(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot, void *data, size_t dataLen);
+void rsdScriptSetGlobalBind(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot, void *data);
+void rsdScriptSetGlobalObj(const android::renderscript::Context *,
+ const android::renderscript::Script *,
+ uint32_t slot, android::renderscript::ObjectBase *data);
+
+void rsdScriptSetGlobal(const android::renderscript::Context *dc,
+ const android::renderscript::Script *script,
+ uint32_t slot,
+ void *data,
+ size_t dataLength);
+void rsdScriptGetGlobal(const android::renderscript::Context *dc,
+ const android::renderscript::Script *script,
+ uint32_t slot,
+ void *data,
+ size_t dataLength);
+void rsdScriptDestroy(const android::renderscript::Context *dc,
+ android::renderscript::Script *script);
+
+
+#endif
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
new file mode 100644
index 000000000000..65461107028a
--- /dev/null
+++ b/libs/rs/driver/rsdCore.cpp
@@ -0,0 +1,186 @@
+/*
+ * 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.
+ */
+
+#include "rsdCore.h"
+#include "rsdBcc.h"
+
+#include <malloc.h>
+#include "rsContext.h"
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sched.h>
+#include <cutils/properties.h>
+#include <cutils/sched_policy.h>
+#include <sys/syscall.h>
+#include <string.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+static void Shutdown(Context *rsc);
+static void SetPriority(const Context *rsc, int32_t priority);
+
+static RsdHalFunctions FunctionTable = {
+ Shutdown,
+ NULL,
+ SetPriority,
+ {
+ rsdScriptInit,
+ rsdScriptInvokeFunction,
+ rsdScriptInvokeRoot,
+ rsdScriptInvokeForEach,
+ rsdScriptInvokeInit,
+ rsdScriptSetGlobalVar,
+ rsdScriptSetGlobalBind,
+ rsdScriptSetGlobalObj,
+ rsdScriptDestroy
+ }
+};
+
+
+
+static void * HelperThreadProc(void *vrsc) {
+ Context *rsc = static_cast<Context *>(vrsc);
+ RsHal *dc = (RsHal *)rsc->mHal.drv;
+
+
+ uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
+
+ //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
+
+ dc->mWorkers.mLaunchSignals[idx].init();
+ dc->mWorkers.mNativeThreadId[idx] = gettid();
+
+#if 0
+ typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
+ cpu_set_t cpuset;
+ memset(&cpuset, 0, sizeof(cpuset));
+ cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
+ int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
+ sizeof(cpuset), &cpuset);
+ LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
+#endif
+
+ int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
+ if (status) {
+ LOGE("pthread_setspecific %i", status);
+ }
+
+ while (!dc->mExit) {
+ dc->mWorkers.mLaunchSignals[idx].wait();
+ if (dc->mWorkers.mLaunchCallback) {
+ dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
+ }
+ android_atomic_dec(&dc->mWorkers.mRunningCount);
+ dc->mWorkers.mCompleteSignal.set();
+ }
+
+ //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
+ return NULL;
+}
+
+void rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
+ RsHal *dc = (RsHal *)rsc->mHal.drv;
+
+ dc->mWorkers.mLaunchData = data;
+ dc->mWorkers.mLaunchCallback = cbk;
+ android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
+ for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
+ dc->mWorkers.mLaunchSignals[ct].set();
+ }
+ while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
+ dc->mWorkers.mCompleteSignal.wait();
+ }
+}
+
+bool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
+ rsc->mHal.funcs = FunctionTable;
+
+ RsHal *dc = (RsHal *)calloc(1, sizeof(RsHal));
+ if (!dc) {
+ LOGE("Calloc for driver hal failed.");
+ return false;
+ }
+ rsc->mHal.drv = dc;
+
+
+ int cpu = sysconf(_SC_NPROCESSORS_ONLN);
+ LOGV("RS Launching thread(s), reported CPU count %i", cpu);
+ if (cpu < 2) cpu = 0;
+
+ dc->mWorkers.mCount = (uint32_t)cpu;
+ dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
+ dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
+ dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
+ dc->mWorkers.mLaunchCallback = NULL;
+
+ dc->mWorkers.mCompleteSignal.init();
+
+ android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
+ android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
+
+ int status;
+ pthread_attr_t threadAttr;
+ status = pthread_attr_init(&threadAttr);
+ if (status) {
+ LOGE("Failed to init thread attribute.");
+ return false;
+ }
+
+ for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
+ status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
+ if (status) {
+ dc->mWorkers.mCount = ct;
+ LOGE("Created fewer than expected number of RS threads.");
+ break;
+ }
+ }
+ while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
+ usleep(100);
+ }
+
+ pthread_attr_destroy(&threadAttr);
+ return true;
+}
+
+
+void SetPriority(const Context *rsc, int32_t priority) {
+ RsHal *dc = (RsHal *)rsc->mHal.drv;
+ for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
+ setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
+ }
+}
+
+void Shutdown(Context *rsc) {
+ RsHal *dc = (RsHal *)rsc->mHal.drv;
+
+ dc->mExit = true;
+ dc->mWorkers.mLaunchData = NULL;
+ dc->mWorkers.mLaunchCallback = NULL;
+ android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
+ for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
+ dc->mWorkers.mLaunchSignals[ct].set();
+ }
+ int status;
+ void *res;
+ for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
+ status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
+ }
+ rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
+}
+
+
diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h
new file mode 100644
index 000000000000..02b2fbc5441c
--- /dev/null
+++ b/libs/rs/driver/rsdCore.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RSD_CORE_H
+#define RSD_CORE_H
+
+#include <rs_hal.h>
+#include <bcc/bcc.h>
+
+#include "rsMutex.h"
+#include "rsSignal.h"
+
+
+typedef void (* InvokeFunc_t)(void);
+typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
+
+typedef struct RsHalRec {
+ uint32_t version_major;
+ uint32_t version_minor;
+
+ struct Workers {
+ volatile int mRunningCount;
+ volatile int mLaunchCount;
+ uint32_t mCount;
+ pthread_t *mThreadId;
+ pid_t *mNativeThreadId;
+ android::renderscript::Signal mCompleteSignal;
+
+ android::renderscript::Signal *mLaunchSignals;
+ WorkerCallback_t mLaunchCallback;
+ void *mLaunchData;
+ };
+ Workers mWorkers;
+ bool mExit;
+} RsHal;
+
+
+
+void rsdLaunchThreads(android::renderscript::Context *rsc, WorkerCallback_t cbk, void *data);
+
+#endif
+
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 7e23cec90805..bbb62007b13f 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -181,10 +181,6 @@ ScriptBindAllocation {
}
-ScriptCBegin {
- }
-
-
ScriptSetTimeZone {
param RsScript s
param const char * timeZone
@@ -246,15 +242,11 @@ ScriptSetVarV {
}
-ScriptCSetText {
- param const char * text
- param uint32_t length
- }
-
ScriptCCreate {
- param const char * packageName
param const char * resName
param const char * cacheDir
+ param const char * text
+ param uint32_t length
ret RsScript
}
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index ec03a158871f..b8ddb0b7cac2 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -29,21 +29,22 @@ Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
: ObjectBase(rsc) {
init(rsc, type);
- mUsageFlags = usages;
- mMipmapControl = mc;
+ mHal.state.usageFlags = usages;
+ mHal.state.mipmapControl = mc;
allocScriptMemory();
- if (mType->getElement()->getHasReferences()) {
- memset(mPtr, 0, mType->getSizeBytes());
+ if (mHal.state.type->getElement()->getHasReferences()) {
+ memset(mHal.state.mallocPtr, 0, mHal.state.type->getSizeBytes());
}
- if (!mPtr) {
+ if (!mHal.state.mallocPtr) {
LOGE("Allocation::Allocation, alloc failure");
}
}
void Allocation::init(Context *rsc, const Type *type) {
- mPtr = NULL;
+ memset(&mHal, 0, sizeof(mHal));
+ mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
mCpuWrite = false;
mCpuRead = false;
@@ -52,8 +53,6 @@ void Allocation::init(Context *rsc, const Type *type) {
mReadWriteRatio = 0;
mUpdateSize = 0;
- mUsageFlags = 0;
- mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
mTextureID = 0;
mBufferID = 0;
@@ -62,16 +61,25 @@ void Allocation::init(Context *rsc, const Type *type) {
mUserBitmapCallback = NULL;
mUserBitmapCallbackData = NULL;
- mType.set(type);
- rsAssert(type);
+ mHal.state.type.set(type);
+ updateCache();
+}
- mPtr = NULL;
+void Allocation::updateCache() {
+ const Type *type = mHal.state.type.get();
+ mHal.state.dimensionX = type->getDimX();
+ mHal.state.dimensionY = type->getDimY();
+ mHal.state.dimensionZ = type->getDimZ();
+ mHal.state.hasFaces = type->getDimFaces();
+ mHal.state.hasMipmaps = type->getDimLOD();
+ mHal.state.elementSizeBytes = type->getElementSizeBytes();
+ mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
}
Allocation::~Allocation() {
if (mUserBitmapCallback != NULL) {
mUserBitmapCallback(mUserBitmapCallbackData);
- mPtr = NULL;
+ mHal.state.mallocPtr = NULL;
}
freeScriptMemory();
#ifndef ANDROID_RS_SERIALIZE
@@ -105,14 +113,14 @@ bool Allocation::fixAllocation() {
}
void Allocation::deferedUploadToTexture(const Context *rsc) {
- mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
+ mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
mUploadDefered = true;
}
uint32_t Allocation::getGLTarget() const {
#ifndef ANDROID_RS_SERIALIZE
if (getIsTexture()) {
- if (mType->getDimFaces()) {
+ if (mHal.state.type->getDimFaces()) {
return GL_TEXTURE_CUBE_MAP;
} else {
return GL_TEXTURE_2D;
@@ -126,14 +134,14 @@ uint32_t Allocation::getGLTarget() const {
}
void Allocation::allocScriptMemory() {
- rsAssert(!mPtr);
- mPtr = malloc(mType->getSizeBytes());
+ rsAssert(!mHal.state.mallocPtr);
+ mHal.state.mallocPtr = malloc(mHal.state.type->getSizeBytes());
}
void Allocation::freeScriptMemory() {
- if (mPtr) {
- free(mPtr);
- mPtr = NULL;
+ if (mHal.state.mallocPtr) {
+ free(mHal.state.mallocPtr);
+ mHal.state.mallocPtr = NULL;
}
}
@@ -153,15 +161,15 @@ void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
void Allocation::uploadToTexture(const Context *rsc) {
#ifndef ANDROID_RS_SERIALIZE
- mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
- GLenum type = mType->getElement()->getComponent().getGLType();
- GLenum format = mType->getElement()->getComponent().getGLFormat();
+ mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
+ GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
+ GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
if (!type || !format) {
return;
}
- if (!mPtr) {
+ if (!mHal.state.mallocPtr) {
return;
}
@@ -184,7 +192,7 @@ void Allocation::uploadToTexture(const Context *rsc) {
upload2DTexture(isFirstUpload);
- if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
+ if (!(mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
freeScriptMemory();
}
@@ -207,14 +215,14 @@ void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
uint32_t lod, RsAllocationCubemapFace face,
uint32_t w, uint32_t h) {
#ifndef ANDROID_RS_SERIALIZE
- GLenum type = mType->getElement()->getComponent().getGLType();
- GLenum format = mType->getElement()->getComponent().getGLFormat();
+ GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
+ GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
GLenum target = (GLenum)getGLTarget();
rsAssert(mTextureID);
glBindTexture(target, mTextureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
GLenum t = GL_TEXTURE_2D;
- if (mType->getDimFaces()) {
+ if (mHal.state.hasFaces) {
t = gFaceOrder[face];
}
glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
@@ -223,57 +231,57 @@ void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
void Allocation::upload2DTexture(bool isFirstUpload) {
#ifndef ANDROID_RS_SERIALIZE
- GLenum type = mType->getElement()->getComponent().getGLType();
- GLenum format = mType->getElement()->getComponent().getGLFormat();
+ GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
+ GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
GLenum target = (GLenum)getGLTarget();
glBindTexture(target, mTextureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
uint32_t faceCount = 1;
- if (mType->getDimFaces()) {
+ if (mHal.state.hasFaces) {
faceCount = 6;
}
for (uint32_t face = 0; face < faceCount; face ++) {
- for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
- const uint8_t *p = (const uint8_t *)mPtr;
- p += mType->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
+ for (uint32_t lod = 0; lod < mHal.state.type->getLODCount(); lod++) {
+ const uint8_t *p = (const uint8_t *)mHal.state.mallocPtr;
+ p += mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
GLenum t = GL_TEXTURE_2D;
- if (mType->getDimFaces()) {
+ if (mHal.state.hasFaces) {
t = gFaceOrder[face];
}
if (isFirstUpload) {
glTexImage2D(t, lod, format,
- mType->getLODDimX(lod), mType->getLODDimY(lod),
+ mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
0, format, type, p);
} else {
glTexSubImage2D(t, lod, 0, 0,
- mType->getLODDimX(lod), mType->getLODDimY(lod),
+ mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
format, type, p);
}
}
}
- if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
+ if (mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
glGenerateMipmap(target);
}
#endif //ANDROID_RS_SERIALIZE
}
void Allocation::deferedUploadToBufferObject(const Context *rsc) {
- mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
+ mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
mUploadDefered = true;
}
void Allocation::uploadToBufferObject(const Context *rsc) {
#ifndef ANDROID_RS_SERIALIZE
- rsAssert(!mType->getDimY());
- rsAssert(!mType->getDimZ());
+ rsAssert(!mHal.state.type->getDimY());
+ rsAssert(!mHal.state.type->getDimZ());
- mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
+ mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
if (!mBufferID) {
glGenBuffers(1, &mBufferID);
@@ -285,7 +293,7 @@ void Allocation::uploadToBufferObject(const Context *rsc) {
}
GLenum target = (GLenum)getGLTarget();
glBindBuffer(target, mBufferID);
- glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
+ glBufferData(target, mHal.state.type->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
glBindBuffer(target, 0);
rsc->checkError("Allocation::uploadToBufferObject");
#endif //ANDROID_RS_SERIALIZE
@@ -298,23 +306,23 @@ void Allocation::uploadCheck(Context *rsc) {
}
void Allocation::read(void *data) {
- memcpy(data, mPtr, mType->getSizeBytes());
+ memcpy(data, mHal.state.mallocPtr, mHal.state.type->getSizeBytes());
}
void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
uint32_t count, const void *data, uint32_t sizeBytes) {
- uint32_t eSize = mType->getElementSizeBytes();
- uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+ uint32_t eSize = mHal.state.type->getElementSizeBytes();
+ uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
ptr += eSize * xoff;
uint32_t size = count * eSize;
if (size != sizeBytes) {
LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
- mType->dumpLOGV("type info");
+ mHal.state.type->dumpLOGV("type info");
return;
}
- if (mType->getElement()->getHasReferences()) {
+ if (mHal.state.hasReferences) {
incRefs(data, count);
decRefs(ptr, count);
}
@@ -326,9 +334,9 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
- uint32_t eSize = mType->getElementSizeBytes();
+ uint32_t eSize = mHal.state.elementSizeBytes;
uint32_t lineSize = eSize * w;
- uint32_t destW = mType->getDimX();
+ uint32_t destW = mHal.state.dimensionX;
//LOGE("data2d %p, %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
@@ -338,14 +346,14 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod,
return;
}
- if (mPtr) {
+ if (mHal.state.mallocPtr) {
const uint8_t *src = static_cast<const uint8_t *>(data);
- uint8_t *dst = static_cast<uint8_t *>(mPtr);
- dst += mType->getLODFaceOffset(lod, face, xoff, yoff);
+ uint8_t *dst = static_cast<uint8_t *>(mHal.state.mallocPtr);
+ dst += mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
//LOGE(" %p %p %i ", dst, src, eSize);
for (uint32_t line=yoff; line < (yoff+h); line++) {
- if (mType->getElement()->getHasReferences()) {
+ if (mHal.state.hasReferences) {
incRefs(src, w);
decRefs(dst, w);
}
@@ -367,24 +375,24 @@ void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
uint32_t cIdx, uint32_t sizeBytes) {
- uint32_t eSize = mType->getElementSizeBytes();
- uint8_t * ptr = static_cast<uint8_t *>(mPtr);
+ uint32_t eSize = mHal.state.elementSizeBytes;
+ uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
ptr += eSize * x;
- if (cIdx >= mType->getElement()->getFieldCount()) {
+ if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
return;
}
- if (x >= mType->getDimX()) {
+ if (x >= mHal.state.dimensionX) {
LOGE("Error Allocation::subElementData X offset %i out of range.", x);
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
return;
}
- const Element * e = mType->getElement()->getField(cIdx);
- ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+ const Element * e = mHal.state.type->getElement()->getField(cIdx);
+ ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
if (sizeBytes != e->getSizeBytes()) {
LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
@@ -404,30 +412,30 @@ void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
const void *data, uint32_t cIdx, uint32_t sizeBytes) {
- uint32_t eSize = mType->getElementSizeBytes();
- uint8_t * ptr = static_cast<uint8_t *>(mPtr);
- ptr += eSize * (x + y * mType->getDimX());
+ uint32_t eSize = mHal.state.elementSizeBytes;
+ uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
+ ptr += eSize * (x + y * mHal.state.dimensionX);
- if (x >= mType->getDimX()) {
+ if (x >= mHal.state.dimensionX) {
LOGE("Error Allocation::subElementData X offset %i out of range.", x);
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
return;
}
- if (y >= mType->getDimY()) {
+ if (y >= mHal.state.dimensionY) {
LOGE("Error Allocation::subElementData X offset %i out of range.", x);
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
return;
}
- if (cIdx >= mType->getElement()->getFieldCount()) {
+ if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
return;
}
- const Element * e = mType->getElement()->getField(cIdx);
- ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
+ const Element * e = mHal.state.type->getElement()->getField(cIdx);
+ ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
if (sizeBytes != e->getSizeBytes()) {
LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
@@ -468,15 +476,15 @@ void Allocation::dumpLOGV(const char *prefix) const {
String8 s(prefix);
s.append(" type ");
- if (mType.get()) {
- mType->dumpLOGV(s.string());
+ if (mHal.state.type.get()) {
+ mHal.state.type->dumpLOGV(s.string());
}
LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
- prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
+ prefix, mHal.state.mallocPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
- prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
+ prefix, mHal.state.usageFlags, mHal.state.mipmapControl, mTextureID, mBufferID);
}
void Allocation::serialize(OStream *stream) const {
@@ -488,13 +496,13 @@ void Allocation::serialize(OStream *stream) const {
// First thing we need to serialize is the type object since it will be needed
// to initialize the class
- mType->serialize(stream);
+ mHal.state.type->serialize(stream);
- uint32_t dataSize = mType->getSizeBytes();
+ uint32_t dataSize = mHal.state.type->getSizeBytes();
// Write how much data we are storing
stream->addU32(dataSize);
// Now write the data
- stream->addByteArray(mPtr, dataSize);
+ stream->addByteArray(mHal.state.mallocPtr, dataSize);
}
Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
@@ -544,7 +552,7 @@ void Allocation::sendDirty() const {
void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
const uint8_t *p = static_cast<const uint8_t *>(ptr);
- const Element *e = mType->getElement();
+ const Element *e = mHal.state.type->getElement();
uint32_t stride = e->getSizeBytes();
p += stride * startOff;
@@ -557,7 +565,7 @@ void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
const uint8_t *p = static_cast<const uint8_t *>(ptr);
- const Element *e = mType->getElement();
+ const Element *e = mHal.state.type->getElement();
uint32_t stride = e->getSizeBytes();
p += stride * startOff;
@@ -572,24 +580,26 @@ void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff
}
void Allocation::resize1D(Context *rsc, uint32_t dimX) {
- Type *t = mType->cloneAndResize1D(rsc, dimX);
+ Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
- uint32_t oldDimX = mType->getDimX();
+ uint32_t oldDimX = mHal.state.dimensionX;
if (dimX == oldDimX) {
return;
}
if (dimX < oldDimX) {
- decRefs(mPtr, oldDimX - dimX, dimX);
+ decRefs(mHal.state.mallocPtr, oldDimX - dimX, dimX);
}
- mPtr = realloc(mPtr, t->getSizeBytes());
+ mHal.state.mallocPtr = realloc(mHal.state.mallocPtr, t->getSizeBytes());
if (dimX > oldDimX) {
- const Element *e = mType->getElement();
+ const Element *e = mHal.state.type->getElement();
uint32_t stride = e->getSizeBytes();
- memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
+ memset(((uint8_t *)mHal.state.mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
}
- mType.set(t);
+
+ mHal.state.type.set(t);
+ updateCache();
}
void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 4f5d5a8e351f..e63140c78666 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -29,10 +29,35 @@ class Allocation : public ObjectBase {
// The graphics equilivent of malloc. The allocation contains a structure of elements.
public:
+ struct Hal {
+ void * drv;
+
+ struct State {
+ ObjectBaseRef<const Type> type;
+ void * mallocPtr;
+
+ uint32_t usageFlags;
+ RsAllocationMipmapControl mipmapControl;
+
+ // Cached fields from the Type and Element
+ // to prevent pointer chasing in critical loops.
+ uint32_t dimensionX;
+ uint32_t dimensionY;
+ uint32_t dimensionZ;
+ uint32_t elementSizeBytes;
+ bool hasMipmaps;
+ bool hasFaces;
+ bool hasReferences;
+ };
+ State state;
+ };
+ Hal mHal;
+
Allocation(Context *rsc, const Type *, uint32_t usages,
RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE);
virtual ~Allocation();
+ void updateCache();
void setCpuWritable(bool);
void setGpuWritable(bool);
@@ -41,8 +66,8 @@ public:
bool fixAllocation();
- void * getPtr() const {return mPtr;}
- const Type * getType() const {return mType.get();}
+ void * getPtr() const {return mHal.state.mallocPtr;}
+ const Type * getType() const {return mHal.state.type.get();}
void syncAll(Context *rsc, RsAllocationUsageType src);
@@ -88,13 +113,13 @@ public:
virtual void uploadCheck(Context *rsc);
bool getIsScript() const {
- return (mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0;
+ return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) != 0;
}
bool getIsTexture() const {
- return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
+ return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) != 0;
}
bool getIsBufferObject() const {
- return (mUsageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
+ return (mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) != 0;
}
void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
@@ -102,14 +127,11 @@ public:
void sendDirty() const;
bool getHasGraphicsMipmaps() const {
- return mMipmapControl != RS_ALLOCATION_MIPMAP_NONE;
+ return mHal.state.mipmapControl != RS_ALLOCATION_MIPMAP_NONE;
}
protected:
- ObjectBaseRef<const Type> mType;
- void * mPtr;
-
Vector<const Program *> mToDirtyList;
// Is we have a non-null user bitmap callback we do not own the bits and
@@ -123,9 +145,6 @@ protected:
bool mGpuWrite;
bool mGpuRead;
- uint32_t mUsageFlags;
- RsAllocationMipmapControl mMipmapControl;
-
// more usage hint data from the application
// which can be used by a driver to pick the best memory type.
// Likely ignored for now
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index c63d183c7b59..c761c75e16b7 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -429,6 +429,8 @@ void Context::displayDebugStats() {
mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
uint32_t bufferLen = strlen(buffer);
+ ObjectBaseRef<Font> lastFont(getFont());
+ setFont(NULL);
float shadowCol = 0.1f;
mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6);
@@ -436,6 +438,7 @@ void Context::displayDebugStats() {
mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7);
+ setFont(lastFont.get());
mStateFont.setFontColor(oldR, oldG, oldB, oldA);
}
@@ -551,56 +554,6 @@ void Context::destroyWorkerThreadResources() {
mExit = true;
}
-void * Context::helperThreadProc(void *vrsc) {
- Context *rsc = static_cast<Context *>(vrsc);
- uint32_t idx = (uint32_t)android_atomic_inc(&rsc->mWorkers.mLaunchCount);
-
- //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
-
- rsc->mWorkers.mLaunchSignals[idx].init();
- rsc->mWorkers.mNativeThreadId[idx] = gettid();
-
-#if 0
- typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
- cpu_set_t cpuset;
- memset(&cpuset, 0, sizeof(cpuset));
- cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
- int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
- sizeof(cpuset), &cpuset);
- LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
-#endif
-
- setpriority(PRIO_PROCESS, rsc->mWorkers.mNativeThreadId[idx], rsc->mThreadPriority);
- int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
- if (status) {
- LOGE("pthread_setspecific %i", status);
- }
-
- while (!rsc->mExit) {
- rsc->mWorkers.mLaunchSignals[idx].wait();
- if (rsc->mWorkers.mLaunchCallback) {
- rsc->mWorkers.mLaunchCallback(rsc->mWorkers.mLaunchData, idx);
- }
- android_atomic_dec(&rsc->mWorkers.mRunningCount);
- rsc->mWorkers.mCompleteSignal.set();
- }
-
- //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
- return NULL;
-}
-
-void Context::launchThreads(WorkerCallback_t cbk, void *data) {
- mWorkers.mLaunchData = data;
- mWorkers.mLaunchCallback = cbk;
- android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
- for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
- mWorkers.mLaunchSignals[ct].set();
- }
- while (android_atomic_acquire_load(&mWorkers.mRunningCount) != 0) {
- mWorkers.mCompleteSignal.wait();
- }
-}
-
void Context::setPriority(int32_t p) {
// Note: If we put this in the proper "background" policy
// the wallpapers can become completly unresponsive at times.
@@ -617,9 +570,6 @@ void Context::setPriority(int32_t p) {
}
#else
setpriority(PRIO_PROCESS, mNativeThreadId, p);
- for (uint32_t ct=0; ct < mWorkers.mCount; ct++) {
- setpriority(PRIO_PROCESS, mWorkers.mNativeThreadId[ct], p);
- }
#endif
}
@@ -685,15 +635,12 @@ bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
timerInit();
timerSet(RS_TIMER_INTERNAL);
- int cpu = sysconf(_SC_NPROCESSORS_ONLN);
- LOGV("RS Launching thread(s), reported CPU count %i", cpu);
- if (cpu < 2) cpu = 0;
+ if (!rsdHalInit(this, 0, 0)) {
+ LOGE("Hal init failed");
+ return false;
+ }
+ mHal.funcs.setPriority(this, mThreadPriority);
- mWorkers.mCount = (uint32_t)cpu;
- mWorkers.mThreadId = (pthread_t *) calloc(mWorkers.mCount, sizeof(pthread_t));
- mWorkers.mNativeThreadId = (pid_t *) calloc(mWorkers.mCount, sizeof(pid_t));
- mWorkers.mLaunchSignals = new Signal[mWorkers.mCount];
- mWorkers.mLaunchCallback = NULL;
status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
if (status) {
LOGE("Failed to start rs context thread.");
@@ -704,23 +651,10 @@ bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
}
if (mError != RS_ERROR_NONE) {
+ LOGE("Errors during thread init");
return false;
}
- mWorkers.mCompleteSignal.init();
- android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
- android_atomic_release_store(0, &mWorkers.mLaunchCount);
- for (uint32_t ct=0; ct < mWorkers.mCount; ct++) {
- status = pthread_create(&mWorkers.mThreadId[ct], &threadAttr, helperThreadProc, this);
- if (status) {
- mWorkers.mCount = ct;
- LOGE("Created fewer than expected number of RS threads.");
- break;
- }
- }
- while (android_atomic_acquire_load(&mWorkers.mRunningCount) != 0) {
- usleep(100);
- }
pthread_attr_destroy(&threadAttr);
return true;
}
@@ -737,17 +671,10 @@ Context::~Context() {
mIO.shutdown();
int status = pthread_join(mThreadId, &res);
- // Cleanup compute threads.
- mWorkers.mLaunchData = NULL;
- mWorkers.mLaunchCallback = NULL;
- android_atomic_release_store(mWorkers.mCount, &mWorkers.mRunningCount);
- for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
- mWorkers.mLaunchSignals[ct].set();
- }
- for (uint32_t ct = 0; ct < mWorkers.mCount; ct++) {
- status = pthread_join(mWorkers.mThreadId[ct], &res);
+
+ if (mHal.funcs.shutdownDriver) {
+ mHal.funcs.shutdownDriver(this);
}
- rsAssert(android_atomic_acquire_load(&mWorkers.mRunningCount) == 0);
// Global structure cleanup.
pthread_mutex_lock(&gInitMutex);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 50f63df44401..72574a60a37d 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -22,6 +22,8 @@
#include "rsAllocation.h"
#include "rsMesh.h"
+#include "rs_hal.h"
+
#ifndef ANDROID_RS_SERIALIZE
#include "rsMutex.h"
#include "rsThreadIO.h"
@@ -71,6 +73,13 @@ namespace renderscript {
class Context {
public:
+ struct Hal {
+ void * drv;
+
+ RsdHalFunctions funcs;
+ };
+ Hal mHal;
+
static Context * createContext(Device *, const RsSurfaceConfig *sc);
~Context();
@@ -81,11 +90,6 @@ public:
// Library mutex (for providing thread-safe calls from the runtime)
static pthread_mutex_t gLibMutex;
- struct ScriptTLSStruct {
- Context * mContext;
- Script * mScript;
- };
-
class PushState {
public:
PushState(Context *);
@@ -103,9 +107,6 @@ public:
ScriptTLSStruct *mTlsStruct;
RsSurfaceConfig mUserSurfaceConfig;
- typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
-
- //StructuredAllocationContext mStateAllocation;
ElementState mStateElement;
TypeState mStateType;
SamplerState mStateSampler;
@@ -216,8 +217,6 @@ public:
uint32_t getMaxVertexUniformVectors() const {return mGL.mMaxVertexUniformVectors;}
uint32_t getMaxVertexAttributes() const {return mGL.mMaxVertexAttribs;}
- void launchThreads(WorkerCallback_t cbk, void *data);
- uint32_t getWorkerPoolSize() const {return (uint32_t)mWorkers.mCount;}
uint32_t getDPI() const {return mDPI;}
void setDPI(uint32_t dpi) {mDPI = dpi;}
@@ -274,20 +273,6 @@ protected:
pthread_t mThreadId;
pid_t mNativeThreadId;
- struct Workers {
- volatile int mRunningCount;
- volatile int mLaunchCount;
- uint32_t mCount;
- pthread_t *mThreadId;
- pid_t *mNativeThreadId;
- Signal mCompleteSignal;
-
- Signal *mLaunchSignals;
- WorkerCallback_t mLaunchCallback;
- void *mLaunchData;
- };
- Workers mWorkers;
-
ObjectBaseRef<Script> mRootScript;
ObjectBaseRef<ProgramFragment> mFragment;
ObjectBaseRef<ProgramVertex> mVertex;
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index afee2a314809..b84014fa31d4 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -21,6 +21,7 @@ using namespace android::renderscript;
Script::Script(Context *rsc) : ObjectBase(rsc) {
memset(&mEnviroment, 0, sizeof(mEnviroment));
+ memset(&mHal, 0, sizeof(mHal));
mSlots = NULL;
mTypes = NULL;
@@ -37,48 +38,38 @@ Script::~Script() {
}
}
-void Script::initSlots() {
- if (mEnviroment.mFieldCount > 0) {
- mSlots = new ObjectBaseRef<Allocation>[mEnviroment.mFieldCount];
- mTypes = new ObjectBaseRef<const Type>[mEnviroment.mFieldCount];
- }
-}
-
void Script::setSlot(uint32_t slot, Allocation *a) {
- if (slot >= mEnviroment.mFieldCount) {
+ //LOGE("setSlot %i %p", slot, a);
+ if (slot >= mHal.info.exportedVariableCount) {
LOGE("Script::setSlot unable to set allocation, invalid slot index");
return;
}
mSlots[slot].set(a);
+ if (a != NULL) {
+ mRSC->mHal.funcs.script.setGlobalBind(mRSC, this, slot, a->getPtr());
+ } else {
+ mRSC->mHal.funcs.script.setGlobalBind(mRSC, this, slot, NULL);
+ }
}
void Script::setVar(uint32_t slot, const void *val, uint32_t len) {
- int32_t *destPtr = ((int32_t **)mEnviroment.mFieldAddress)[slot];
- if (destPtr) {
- //LOGE("setVar f1 %f", ((const float *)destPtr)[0]);
- //LOGE("setVar %p %i", destPtr, len);
- memcpy(destPtr, val, len);
- //LOGE("setVar f2 %f", ((const float *)destPtr)[0]);
- } else {
- //if (rsc->props.mLogScripts) {
- LOGV("Calling setVar on slot = %i which is null", slot);
- //}
+ //LOGE("setVar %i %p %i", slot, val, len);
+ if (slot >= mHal.info.exportedVariableCount) {
+ LOGE("Script::setVar unable to set allocation, invalid slot index");
+ return;
}
+ mRSC->mHal.funcs.script.setGlobalVar(mRSC, this, slot, (void *)val, len);
}
void Script::setVarObj(uint32_t slot, ObjectBase *val) {
- ObjectBase **destPtr = ((ObjectBase ***)mEnviroment.mFieldAddress)[slot];
-
- if (destPtr) {
- if (val != NULL) {
- val->incSysRef();
- }
- if (*destPtr) {
- (*destPtr)->decSysRef();
- }
- *destPtr = val;
+ //LOGE("setVarObj %i %p", slot, val);
+ if (slot >= mHal.info.exportedVariableCount) {
+ LOGE("Script::setVarObj unable to set allocation, invalid slot index");
+ return;
}
+ //LOGE("setvarobj %i %p", slot, val);
+ mRSC->mHal.funcs.script.setGlobalObj(mRSC, this, slot, val);
}
namespace android {
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index bad095bcfcdf..671fbe6746f4 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -31,6 +31,45 @@ class ProgramStore;
class Script : public ObjectBase {
public:
+ struct Hal {
+ void * drv;
+
+ struct State {
+ ObjectBaseRef<const Type> type;
+ void * mallocPtr;
+
+ uint32_t usageFlags;
+ RsAllocationMipmapControl mipmapControl;
+
+ // Cached fields from the Type and Element
+ // to prevent pointer chasing in critical loops.
+ uint32_t dimensionX;
+ uint32_t dimensionY;
+ uint32_t dimensionZ;
+ uint32_t elementSizeBytes;
+ bool hasMipmaps;
+ bool hasFaces;
+ bool hasReferences;
+ };
+ State state;
+
+ struct DriverInfo {
+ int mVersionMajor;
+ int mVersionMinor;
+
+ size_t exportedVariableCount;
+ size_t exportedFunctionCount;
+ size_t exportedPragmaCount;
+ char const **exportedPragmaKeyList;
+ char const **exportedPragmaValueList;
+
+ int (* root)();
+ bool isThreadable;
+ };
+ DriverInfo info;
+ };
+ Hal mHal;
+
typedef void (* InvokeFunc_t)(void);
Script(Context *);
@@ -45,16 +84,6 @@ public:
ObjectBaseRef<ProgramFragment> mFragment;
ObjectBaseRef<ProgramRaster> mRaster;
ObjectBaseRef<ProgramStore> mFragmentStore;
-
- uint32_t mInvokeFunctionCount;
- InvokeFunc_t *mInvokeFunctions;
- uint32_t mFieldCount;
- void ** mFieldAddress;
-
- char * mScriptText;
- uint32_t mScriptTextLength;
-
- bool mIsThreadable;
};
Enviroment_t mEnviroment;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index e12926b0a641..d5c486b14d3d 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -19,9 +19,6 @@
#include "rsMatrix.h"
#include "utils/Timers.h"
#include "utils/StopWatch.h"
-extern "C" {
-#include "libdex/ZipArchive.h"
-}
#include <GLES/gl.h>
#include <GLES/glext.h>
@@ -36,94 +33,18 @@ using namespace android::renderscript;
Context * rsc = tls->mContext; \
ScriptC * sc = (ScriptC *) tls->mScript
-// Input: cacheDir
-// Input: resName
-// Input: extName
-//
-// Note: cacheFile = resName + extName
-//
-// Output: Returns cachePath == cacheDir + cacheFile
-char *genCacheFileName(const char *cacheDir,
- const char *resName,
- const char *extName) {
- char cachePath[512];
- char cacheFile[sizeof(cachePath)];
- const size_t kBufLen = sizeof(cachePath) - 1;
-
- cacheFile[0] = '\0';
- // Note: resName today is usually something like
- // "/com.android.fountain:raw/fountain"
- if (resName[0] != '/') {
- // Get the absolute path of the raw/***.bc file.
-
- // Generate the absolute path. This doesn't do everything it
- // should, e.g. if resName is "./out/whatever" it doesn't crunch
- // the leading "./" out because this if-block is not triggered,
- // but it'll make do.
- //
- if (getcwd(cacheFile, kBufLen) == NULL) {
- LOGE("Can't get CWD while opening raw/***.bc file\n");
- return NULL;
- }
- // Append "/" at the end of cacheFile so far.
- strncat(cacheFile, "/", kBufLen);
- }
-
- // cacheFile = resName + extName
- //
- strncat(cacheFile, resName, kBufLen);
- if (extName != NULL) {
- // TODO(srhines): strncat() is a bit dangerous
- strncat(cacheFile, extName, kBufLen);
- }
-
- // Turn the path into a flat filename by replacing
- // any slashes after the first one with '@' characters.
- char *cp = cacheFile + 1;
- while (*cp != '\0') {
- if (*cp == '/') {
- *cp = '@';
- }
- cp++;
- }
-
- // Tack on the file name for the actual cache file path.
- strncpy(cachePath, cacheDir, kBufLen);
- strncat(cachePath, cacheFile, kBufLen);
-
- LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
- return strdup(cachePath);
-}
-
ScriptC::ScriptC(Context *rsc) : Script(rsc) {
- mBccScript = NULL;
- memset(&mProgram, 0, sizeof(mProgram));
}
ScriptC::~ScriptC() {
- if (mBccScript) {
- if (mProgram.mObjectSlotList) {
- for (size_t ct=0; ct < mProgram.mObjectSlotCount; ct++) {
- setVarObj(mProgram.mObjectSlotList[ct], NULL);
- }
- delete [] mProgram.mObjectSlotList;
- mProgram.mObjectSlotList = NULL;
- mProgram.mObjectSlotCount = 0;
- }
-
-
- LOGD(">>>> ~ScriptC bccDisposeScript(%p)", mBccScript);
- bccDisposeScript(mBccScript);
- }
- free(mEnviroment.mScriptText);
- mEnviroment.mScriptText = NULL;
+ mRSC->mHal.funcs.script.destroy(mRSC, this);
}
void ScriptC::setupScript(Context *rsc) {
mEnviroment.mStartTimeMillis
= nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC));
- for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) {
+ for (uint32_t ct=0; ct < mHal.info.exportedVariableCount; ct++) {
if (mSlots[ct].get() && !mTypes[ct].get()) {
mTypes[ct].set(mSlots[ct]->getType());
}
@@ -134,27 +55,17 @@ void ScriptC::setupScript(Context *rsc) {
if (mSlots[ct].get()) {
ptr = mSlots[ct]->getPtr();
}
- void **dest = ((void ***)mEnviroment.mFieldAddress)[ct];
- if (rsc->props.mLogScripts) {
- if (mSlots[ct].get() != NULL) {
- LOGV("%p ScriptC::setupScript slot=%i dst=%p src=%p type=%p", rsc, ct, dest, ptr, mSlots[ct]->getType());
- } else {
- LOGV("%p ScriptC::setupScript slot=%i dst=%p src=%p type=null", rsc, ct, dest, ptr);
- }
- }
-
- if (dest) {
- *dest = ptr;
- }
+ rsc->mHal.funcs.script.setGlobalBind(rsc, this, ct, ptr);
}
}
const Allocation *ScriptC::ptrToAllocation(const void *ptr) const {
+ //LOGE("ptr to alloc %p", ptr);
if (!ptr) {
return NULL;
}
- for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) {
+ for (uint32_t ct=0; ct < mHal.info.exportedVariableCount; ct++) {
if (!mSlots[ct].get())
continue;
if (mSlots[ct]->getPtr() == ptr) {
@@ -165,15 +76,6 @@ const Allocation *ScriptC::ptrToAllocation(const void *ptr) const {
return NULL;
}
-Script * ScriptC::setTLS(Script *sc) {
- Context::ScriptTLSStruct * tls = (Context::ScriptTLSStruct *)
- pthread_getspecific(Context::gThreadTLSKey);
- rsAssert(tls);
- Script *old = tls->mScript;
- tls->mScript = sc;
- return old;
-}
-
void ScriptC::setupGLState(Context *rsc) {
if (mEnviroment.mFragmentStore.get()) {
rsc->setProgramStore(mEnviroment.mFragmentStore.get());
@@ -190,7 +92,7 @@ void ScriptC::setupGLState(Context *rsc) {
}
uint32_t ScriptC::run(Context *rsc) {
- if (mProgram.mRoot == NULL) {
+ if (mHal.info.root == NULL) {
rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script");
return 0;
}
@@ -199,235 +101,45 @@ uint32_t ScriptC::run(Context *rsc) {
setupScript(rsc);
uint32_t ret = 0;
- Script * oldTLS = setTLS(this);
if (rsc->props.mLogScripts) {
- LOGV("%p ScriptC::run invoking root, ptr %p", rsc, mProgram.mRoot);
+ LOGV("%p ScriptC::run invoking root, ptr %p", rsc, mHal.info.root);
}
- ret = mProgram.mRoot();
+ ret = rsc->mHal.funcs.script.invokeRoot(rsc, this);
if (rsc->props.mLogScripts) {
LOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret);
}
- setTLS(oldTLS);
return ret;
}
-typedef struct {
- Context *rsc;
- ScriptC *script;
- const Allocation * ain;
- Allocation * aout;
- const void * usr;
-
- uint32_t mSliceSize;
- volatile int mSliceNum;
-
- const uint8_t *ptrIn;
- uint32_t eStrideIn;
- uint8_t *ptrOut;
- uint32_t eStrideOut;
-
- uint32_t xStart;
- uint32_t xEnd;
- uint32_t yStart;
- uint32_t yEnd;
- uint32_t zStart;
- uint32_t zEnd;
- uint32_t arrayStart;
- uint32_t arrayEnd;
-
- uint32_t dimX;
- uint32_t dimY;
- uint32_t dimZ;
- uint32_t dimArray;
-} MTLaunchStruct;
-typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t);
-
-static void wc_xy(void *usr, uint32_t idx) {
- MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
-
- while (1) {
- uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
- uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize;
- uint32_t yEnd = yStart + mtls->mSliceSize;
- yEnd = rsMin(yEnd, mtls->yEnd);
- if (yEnd <= yStart) {
- return;
- }
-
- //LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
- //LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
- for (uint32_t y = yStart; y < yEnd; y++) {
- uint32_t offset = mtls->dimX * y;
- uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset);
- const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset);
-
- for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) {
- ((rs_t)mtls->script->mProgram.mRoot) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0);
- xPtrIn += mtls->eStrideIn;
- xPtrOut += mtls->eStrideOut;
- }
- }
- }
-}
-
-static void wc_x(void *usr, uint32_t idx) {
- MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
-
- while (1) {
- uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
- uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize;
- uint32_t xEnd = xStart + mtls->mSliceSize;
- xEnd = rsMin(xEnd, mtls->xEnd);
- if (xEnd <= xStart) {
- return;
- }
-
- //LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd);
- //LOGE("usr ptr in %p, out %p", mtls->ptrIn, mtls->ptrOut);
- uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * xStart);
- const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * xStart);
- for (uint32_t x = xStart; x < xEnd; x++) {
- ((rs_t)mtls->script->mProgram.mRoot) (xPtrIn, xPtrOut, mtls->usr, x, 0, 0, 0);
- xPtrIn += mtls->eStrideIn;
- xPtrOut += mtls->eStrideOut;
- }
- }
-}
void ScriptC::runForEach(Context *rsc,
const Allocation * ain,
Allocation * aout,
const void * usr,
const RsScriptCall *sc) {
- MTLaunchStruct mtls;
- memset(&mtls, 0, sizeof(mtls));
- Context::PushState ps(rsc);
-
- if (ain) {
- mtls.dimX = ain->getType()->getDimX();
- mtls.dimY = ain->getType()->getDimY();
- mtls.dimZ = ain->getType()->getDimZ();
- //mtls.dimArray = ain->getType()->getDimArray();
- } else if (aout) {
- mtls.dimX = aout->getType()->getDimX();
- mtls.dimY = aout->getType()->getDimY();
- mtls.dimZ = aout->getType()->getDimZ();
- //mtls.dimArray = aout->getType()->getDimArray();
- } else {
- rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
- return;
- }
-
- if (!sc || (sc->xEnd == 0)) {
- mtls.xEnd = mtls.dimX;
- } else {
- rsAssert(sc->xStart < mtls.dimX);
- rsAssert(sc->xEnd <= mtls.dimX);
- rsAssert(sc->xStart < sc->xEnd);
- mtls.xStart = rsMin(mtls.dimX, sc->xStart);
- mtls.xEnd = rsMin(mtls.dimX, sc->xEnd);
- if (mtls.xStart >= mtls.xEnd) return;
- }
-
- if (!sc || (sc->yEnd == 0)) {
- mtls.yEnd = mtls.dimY;
- } else {
- rsAssert(sc->yStart < mtls.dimY);
- rsAssert(sc->yEnd <= mtls.dimY);
- rsAssert(sc->yStart < sc->yEnd);
- mtls.yStart = rsMin(mtls.dimY, sc->yStart);
- mtls.yEnd = rsMin(mtls.dimY, sc->yEnd);
- if (mtls.yStart >= mtls.yEnd) return;
- }
-
- mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd);
- mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd);
- mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd);
- mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd);
- rsAssert(ain->getType()->getDimZ() == 0);
+ Context::PushState ps(rsc);
setupGLState(rsc);
setupScript(rsc);
- Script * oldTLS = setTLS(this);
-
- mtls.rsc = rsc;
- mtls.ain = ain;
- mtls.aout = aout;
- mtls.script = this;
- mtls.usr = usr;
- mtls.mSliceSize = 10;
- mtls.mSliceNum = 0;
-
- mtls.ptrIn = NULL;
- mtls.eStrideIn = 0;
- if (ain) {
- mtls.ptrIn = (const uint8_t *)ain->getPtr();
- mtls.eStrideIn = ain->getType()->getElementSizeBytes();
- }
-
- mtls.ptrOut = NULL;
- mtls.eStrideOut = 0;
- if (aout) {
- mtls.ptrOut = (uint8_t *)aout->getPtr();
- mtls.eStrideOut = aout->getType()->getElementSizeBytes();
- }
-
- if ((rsc->getWorkerPoolSize() > 1) && mEnviroment.mIsThreadable) {
- if (mtls.dimY > 1) {
- rsc->launchThreads(wc_xy, &mtls);
- } else {
- rsc->launchThreads(wc_x, &mtls);
- }
-
- //LOGE("launch 1");
- } else {
- //LOGE("launch 3");
- for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) {
- for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) {
- for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) {
- uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar +
- mtls.dimX * mtls.dimY * z +
- mtls.dimX * y;
- uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset);
- const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset);
-
- for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) {
- ((rs_t)mProgram.mRoot) (xPtrIn, xPtrOut, usr, x, y, z, ar);
- xPtrIn += mtls.eStrideIn;
- xPtrOut += mtls.eStrideOut;
- }
- }
- }
- }
- }
-
- setTLS(oldTLS);
+ rsc->mHal.funcs.script.invokeForEach(rsc, this, ain, aout, usr, 0, sc);
}
void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len) {
- if ((slot >= mEnviroment.mInvokeFunctionCount) ||
- (mEnviroment.mInvokeFunctions[slot] == NULL)) {
+ if (slot >= mHal.info.exportedFunctionCount) {
rsc->setError(RS_ERROR_BAD_SCRIPT, "Calling invoke on bad script");
return;
}
setupScript(rsc);
- Script * oldTLS = setTLS(this);
if (rsc->props.mLogScripts) {
- LOGV("%p ScriptC::Invoke invoking slot %i, ptr %p", rsc, slot, mEnviroment.mInvokeFunctions[slot]);
- }
- ((void (*)(const void *, uint32_t))
- mEnviroment.mInvokeFunctions[slot])(data, len);
- if (rsc->props.mLogScripts) {
- LOGV("%p ScriptC::Invoke complete", rsc);
+ LOGV("%p ScriptC::Invoke invoking slot %i, ptr %p", rsc, slot, this);
}
-
- setTLS(oldTLS);
+ rsc->mHal.funcs.script.invokeFunction(rsc, this, slot, data, len);
}
ScriptCState::ScriptCState() {
@@ -440,9 +152,9 @@ static void* symbolLookup(void* pContext, char const* name) {
const ScriptCState::SymbolTable_t *sym;
ScriptC *s = (ScriptC *)pContext;
if (!strcmp(name, "__isThreadable")) {
- return (void*) s->mEnviroment.mIsThreadable;
+ return (void*) s->mHal.info.isThreadable;
} else if (!strcmp(name, "__clearThreadable")) {
- s->mEnviroment.mIsThreadable = false;
+ s->mHal.info.isThreadable = false;
return NULL;
}
sym = ScriptCState::lookupSymbol(name);
@@ -453,7 +165,7 @@ static void* symbolLookup(void* pContext, char const* name) {
sym = ScriptCState::lookupSymbolGL(name);
}
if (sym) {
- s->mEnviroment.mIsThreadable &= sym->threadable;
+ s->mHal.info.isThreadable &= sym->threadable;
return sym->mPtr;
}
LOGE("ScriptC sym lookup failed for %s", name);
@@ -465,144 +177,86 @@ extern const char rs_runtime_lib_bc[];
extern unsigned rs_runtime_lib_bc_size;
#endif
-bool ScriptCState::runCompiler(Context *rsc,
- ScriptC *s,
- const char *resName,
- const char *cacheDir) {
- s->mBccScript = bccCreateScript();
+bool ScriptC::runCompiler(Context *rsc,
+ const char *resName,
+ const char *cacheDir,
+ const uint8_t *bitcode,
+ size_t bitcodeLen) {
- s->mEnviroment.mIsThreadable = true;
+ //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
- if (bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s) != 0) {
- LOGE("bcc: FAILS to register symbol callback");
- return false;
- }
+ rsc->mHal.funcs.script.scriptInit(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0, symbolLookup);
- if (bccReadBC(s->mBccScript,
- resName,
- s->mEnviroment.mScriptText,
- s->mEnviroment.mScriptTextLength, 0) != 0) {
- LOGE("bcc: FAILS to read bitcode");
- return false;
- }
+ mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
+ mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
+ mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
+ mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
-#if 1
- if (bccLinkFile(s->mBccScript, "/system/lib/libclcore.bc", 0) != 0) {
- LOGE("bcc: FAILS to link bitcode");
- return false;
- }
-#endif
- char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
-
- if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
- LOGE("bcc: FAILS to prepare executable");
- return false;
- }
+ rsc->mHal.funcs.script.invokeInit(rsc, this);
- free(cachePath);
-
- s->mProgram.mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(s->mBccScript, "root"));
- s->mProgram.mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(s->mBccScript, "init"));
-
- if (s->mProgram.mInit) {
- s->mProgram.mInit();
- }
-
- s->mEnviroment.mInvokeFunctionCount = bccGetExportFuncCount(s->mBccScript);
- if (s->mEnviroment.mInvokeFunctionCount <= 0)
- s->mEnviroment.mInvokeFunctions = NULL;
- else {
- s->mEnviroment.mInvokeFunctions = (Script::InvokeFunc_t*) calloc(s->mEnviroment.mInvokeFunctionCount, sizeof(Script::InvokeFunc_t));
- bccGetExportFuncList(s->mBccScript, s->mEnviroment.mInvokeFunctionCount, (void **) s->mEnviroment.mInvokeFunctions);
- }
-
- s->mEnviroment.mFieldCount = bccGetExportVarCount(s->mBccScript);
- if (s->mEnviroment.mFieldCount <= 0)
- s->mEnviroment.mFieldAddress = NULL;
- else {
- s->mEnviroment.mFieldAddress = (void **) calloc(s->mEnviroment.mFieldCount, sizeof(void *));
- bccGetExportVarList(s->mBccScript, s->mEnviroment.mFieldCount, (void **) s->mEnviroment.mFieldAddress);
- s->initSlots();
- }
-
- s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
- s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
- s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
- s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster());
-
- const static int pragmaMax = 16;
- size_t pragmaCount = bccGetPragmaCount(s->mBccScript);
- char const *keys[pragmaMax];
- char const *values[pragmaMax];
- bccGetPragmaList(s->mBccScript, pragmaMax, keys, values);
-
- for (size_t i=0; i < pragmaCount; ++i) {
+ for (size_t i=0; i < mHal.info.exportedPragmaCount; ++i) {
+ const char * key = mHal.info.exportedPragmaKeyList[i];
+ const char * value = mHal.info.exportedPragmaValueList[i];
//LOGE("pragma %s %s", keys[i], values[i]);
- if (!strcmp(keys[i], "version")) {
- if (!strcmp(values[i], "1")) {
+ if (!strcmp(key, "version")) {
+ if (!strcmp(value, "1")) {
continue;
}
- LOGE("Invalid version pragma value: %s\n", values[i]);
+ LOGE("Invalid version pragma value: %s\n", value);
return false;
}
- if (!strcmp(keys[i], "stateVertex")) {
- if (!strcmp(values[i], "default")) {
+ if (!strcmp(key, "stateVertex")) {
+ if (!strcmp(value, "default")) {
continue;
}
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mVertex.clear();
+ if (!strcmp(value, "parent")) {
+ mEnviroment.mVertex.clear();
continue;
}
- LOGE("Unrecognized value %s passed to stateVertex", values[i]);
+ LOGE("Unrecognized value %s passed to stateVertex", value);
return false;
}
- if (!strcmp(keys[i], "stateRaster")) {
- if (!strcmp(values[i], "default")) {
+ if (!strcmp(key, "stateRaster")) {
+ if (!strcmp(value, "default")) {
continue;
}
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mRaster.clear();
+ if (!strcmp(value, "parent")) {
+ mEnviroment.mRaster.clear();
continue;
}
- LOGE("Unrecognized value %s passed to stateRaster", values[i]);
+ LOGE("Unrecognized value %s passed to stateRaster", value);
return false;
}
- if (!strcmp(keys[i], "stateFragment")) {
- if (!strcmp(values[i], "default")) {
+ if (!strcmp(key, "stateFragment")) {
+ if (!strcmp(value, "default")) {
continue;
}
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mFragment.clear();
+ if (!strcmp(value, "parent")) {
+ mEnviroment.mFragment.clear();
continue;
}
- LOGE("Unrecognized value %s passed to stateFragment", values[i]);
+ LOGE("Unrecognized value %s passed to stateFragment", value);
return false;
}
- if (!strcmp(keys[i], "stateStore")) {
- if (!strcmp(values[i], "default")) {
+ if (!strcmp(key, "stateStore")) {
+ if (!strcmp(value, "default")) {
continue;
}
- if (!strcmp(values[i], "parent")) {
- s->mEnviroment.mFragmentStore.clear();
+ if (!strcmp(value, "parent")) {
+ mEnviroment.mFragmentStore.clear();
continue;
}
- LOGE("Unrecognized value %s passed to stateStore", values[i]);
+ LOGE("Unrecognized value %s passed to stateStore", value);
return false;
}
}
- size_t objectSlotCount = bccGetObjectSlotCount(s->mBccScript);
- uint32_t *objectSlots = NULL;
- if (objectSlotCount) {
- objectSlots = new uint32_t[objectSlotCount];
- bccGetObjectSlotList(s->mBccScript, objectSlotCount, objectSlots);
- s->mProgram.mObjectSlotList = objectSlots;
- s->mProgram.mObjectSlotCount = objectSlotCount;
- }
+ mSlots = new ObjectBaseRef<Allocation>[mHal.info.exportedVariableCount];
+ mTypes = new ObjectBaseRef<const Type>[mHal.info.exportedVariableCount];
return true;
}
@@ -610,39 +264,19 @@ bool ScriptCState::runCompiler(Context *rsc,
namespace android {
namespace renderscript {
-void rsi_ScriptCBegin(Context * rsc) {
-}
-
-void rsi_ScriptCSetText(Context *rsc, const char *text, uint32_t len) {
- ScriptCState *ss = &rsc->mScriptC;
-
- char *t = (char *)malloc(len + 1);
- memcpy(t, text, len);
- t[len] = 0;
- ss->mScriptText = t;
- ss->mScriptLen = len;
-}
-
-
RsScript rsi_ScriptCCreate(Context *rsc,
- const char *packageName /* deprecated */,
- const char *resName,
- const char *cacheDir)
+ const char *resName, const char *cacheDir,
+ const char *text, uint32_t len)
{
- ScriptCState *ss = &rsc->mScriptC;
-
ScriptC *s = new ScriptC(rsc);
- s->mEnviroment.mScriptText = ss->mScriptText;
- s->mEnviroment.mScriptTextLength = ss->mScriptLen;
- ss->mScriptText = NULL;
- ss->mScriptLen = 0;
- s->incUserRef();
- if (!ss->runCompiler(rsc, s, resName, cacheDir)) {
+ if (!s->runCompiler(rsc, resName, cacheDir, (uint8_t *)text, len)) {
// Error during compile, destroy s and return null.
delete s;
return NULL;
}
+
+ s->incUserRef();
return s;
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 2c74b5b3ef4e..2edeb9b42c35 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -21,7 +21,6 @@
#include "RenderScriptEnv.h"
-struct BCCOpaqueScript;
// ---------------------------------------------------------------------------
namespace android {
@@ -36,21 +35,6 @@ public:
ScriptC(Context *);
virtual ~ScriptC();
- struct Program_t {
- int mVersionMajor;
- int mVersionMinor;
-
- RunScript_t mRoot;
- VoidFunc_t mInit;
-
- uint32_t * mObjectSlotList;
- uint32_t mObjectSlotCount;
- };
-
-
- Program_t mProgram;
-
- BCCOpaqueScript *mBccScript;
const Allocation *ptrToAllocation(const void *) const;
@@ -69,7 +53,10 @@ public:
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_SCRIPT_C; }
static Type *createFromStream(Context *rsc, IStream *stream) { return NULL; }
-protected:
+ bool runCompiler(Context *rsc, const char *resName, const char *cacheDir,
+ const uint8_t *bitcode, size_t bitcodeLen);
+
+//protected:
void setupScript(Context *);
void setupGLState(Context *);
Script * setTLS(Script *);
@@ -83,8 +70,6 @@ public:
char * mScriptText;
size_t mScriptLen;
- bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
-
struct SymbolTable_t {
const char * mName;
void * mPtr;
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 23230a630809..4e8cbdcc60be 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -25,8 +25,8 @@
using namespace android;
using namespace android::renderscript;
-#define GET_TLS() Context::ScriptTLSStruct * tls = \
- (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+#define GET_TLS() ScriptTLSStruct * tls = \
+ (ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
Context * rsc = tls->mContext; \
ScriptC * sc = (ScriptC *) tls->mScript
@@ -141,90 +141,74 @@ static float SC_getDt() {
//
//////////////////////////////////////////////////////////////////////////////
-static uint32_t SC_allocGetDimX(RsAllocation va) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static uint32_t SC_allocGetDimX(Allocation *a) {
CHECK_OBJ(a);
- //LOGE("SC_allocGetDimX a=%p type=%p", a, a->getType());
- return a->getType()->getDimX();
+ return a->mHal.state.dimensionX;
}
-static uint32_t SC_allocGetDimY(RsAllocation va) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static uint32_t SC_allocGetDimY(Allocation *a) {
CHECK_OBJ(a);
- return a->getType()->getDimY();
+ return a->mHal.state.dimensionY;
}
-static uint32_t SC_allocGetDimZ(RsAllocation va) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static uint32_t SC_allocGetDimZ(Allocation *a) {
CHECK_OBJ(a);
- return a->getType()->getDimZ();
+ return a->mHal.state.dimensionZ;
}
-static uint32_t SC_allocGetDimLOD(RsAllocation va) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static uint32_t SC_allocGetDimLOD(Allocation *a) {
CHECK_OBJ(a);
- return a->getType()->getDimLOD();
+ return a->mHal.state.hasMipmaps;
}
-static uint32_t SC_allocGetDimFaces(RsAllocation va) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static uint32_t SC_allocGetDimFaces(Allocation *a) {
CHECK_OBJ(a);
- return a->getType()->getDimFaces();
+ return a->mHal.state.hasFaces;
}
-static const void * SC_getElementAtX(RsAllocation va, uint32_t x) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static const void * SC_getElementAtX(Allocation *a, uint32_t x) {
CHECK_OBJ(a);
- const Type *t = a->getType();
- CHECK_OBJ(t);
const uint8_t *p = (const uint8_t *)a->getPtr();
- return &p[t->getElementSizeBytes() * x];
+ return &p[a->mHal.state.elementSizeBytes * x];
}
-static const void * SC_getElementAtXY(RsAllocation va, uint32_t x, uint32_t y) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static const void * SC_getElementAtXY(Allocation *a, uint32_t x, uint32_t y) {
CHECK_OBJ(a);
- const Type *t = a->getType();
- CHECK_OBJ(t);
const uint8_t *p = (const uint8_t *)a->getPtr();
- return &p[t->getElementSizeBytes() * (x + y*t->getDimX())];
+ return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX)];
}
-static const void * SC_getElementAtXYZ(RsAllocation va, uint32_t x, uint32_t y, uint32_t z) {
- const Allocation *a = static_cast<const Allocation *>(va);
+static const void * SC_getElementAtXYZ(Allocation *a, uint32_t x, uint32_t y, uint32_t z) {
CHECK_OBJ(a);
- const Type *t = a->getType();
- CHECK_OBJ(t);
const uint8_t *p = (const uint8_t *)a->getPtr();
- return &p[t->getElementSizeBytes() * (x + y*t->getDimX())];
+ return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX +
+ z * a->mHal.state.dimensionX * a->mHal.state.dimensionY)];
}
-static void SC_setObject(void **vdst, void * vsrc) {
- //LOGE("SC_setObject %p,%p %p", vdst, *vdst, vsrc);
- if (vsrc) {
- CHECK_OBJ(vsrc);
- static_cast<ObjectBase *>(vsrc)->incSysRef();
+void android::renderscript::rsiSetObject(ObjectBase **dst, ObjectBase * src) {
+ //LOGE("rsiSetObject %p,%p %p", vdst, *vdst, vsrc);
+ if (src) {
+ CHECK_OBJ(src);
+ src->incSysRef();
}
- if (vdst[0]) {
- CHECK_OBJ(vdst[0]);
- static_cast<ObjectBase *>(vdst[0])->decSysRef();
+ if (dst[0]) {
+ CHECK_OBJ(dst[0]);
+ dst[0]->decSysRef();
}
- *vdst = vsrc;
- //LOGE("SC_setObject *");
+ *dst = src;
}
-static void SC_clearObject(void **vdst) {
- //LOGE("SC_clearObject %p,%p", vdst, *vdst);
- if (vdst[0]) {
- CHECK_OBJ(vdst[0]);
- static_cast<ObjectBase *>(vdst[0])->decSysRef();
+void android::renderscript::rsiClearObject(ObjectBase **dst) {
+ //LOGE("rsiClearObject %p,%p", vdst, *vdst);
+ if (dst[0]) {
+ CHECK_OBJ(dst[0]);
+ dst[0]->decSysRef();
}
- *vdst = NULL;
- //LOGE("SC_clearObject *");
+ *dst = NULL;
}
-static bool SC_isObject(RsAllocation vsrc) {
- return vsrc != NULL;
+bool android::renderscript::rsiIsObject(const ObjectBase *src) {
+ return src != NULL;
}
static void SC_debugF(const char *s, float f) {
@@ -873,49 +857,49 @@ static ScriptCState::SymbolTable_t gSyms[] = {
{ "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY, true },
{ "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ, true },
- { "_Z11rsSetObjectP10rs_elementS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP10rs_element", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject10rs_element", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP10rs_elementS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP10rs_element", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject10rs_element", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP7rs_typeS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP7rs_type", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject7rs_type", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP7rs_typeS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP7rs_type", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject7rs_type", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP13rs_allocationS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP13rs_allocation", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject13rs_allocation", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP13rs_allocationS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP13rs_allocation", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject13rs_allocation", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP10rs_samplerS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP10rs_sampler", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject10rs_sampler", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP10rs_samplerS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP10rs_sampler", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject10rs_sampler", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP9rs_scriptS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP9rs_script", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject9rs_script", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP9rs_scriptS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP9rs_script", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject9rs_script", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP7rs_mesh", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject7rs_mesh", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP7rs_meshS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP7rs_mesh", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject7rs_mesh", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP19rs_program_fragment", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject19rs_program_fragment", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP19rs_program_fragmentS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP19rs_program_fragment", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject19rs_program_fragment", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP17rs_program_vertex", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject17rs_program_vertex", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP17rs_program_vertexS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP17rs_program_vertex", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject17rs_program_vertex", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP17rs_program_raster", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject17rs_program_raster", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP17rs_program_rasterS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP17rs_program_raster", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject17rs_program_raster", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP16rs_program_store", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject16rs_program_store", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP16rs_program_storeS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP16rs_program_store", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject16rs_program_store", (void *)&rsiIsObject, true },
- { "_Z11rsSetObjectP7rs_fontS_", (void *)&SC_setObject, true },
- { "_Z13rsClearObjectP7rs_font", (void *)&SC_clearObject, true },
- { "_Z10rsIsObject7rs_font", (void *)&SC_isObject, true },
+ { "_Z11rsSetObjectP7rs_fontS_", (void *)&rsiSetObject, true },
+ { "_Z13rsClearObjectP7rs_font", (void *)&rsiClearObject, true },
+ { "_Z10rsIsObject7rs_font", (void *)&rsiIsObject, true },
{ "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_allocationMarkDirty, true },
@@ -1000,7 +984,7 @@ static ScriptCState::SymbolTable_t gSyms[] = {
{ "_Z17rsMatrixTransposeP12rs_matrix4x4", (void *)&SC_MatrixTranspose_2x2, true },
{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach, false },
- //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2, true },
+ //{ "_Z9rsForEach9rs_script13rs_allocationS0_PKv", (void *)&SC_ForEach2, false },
////////////////////////////////////////////////////////////////////
@@ -1021,3 +1005,4 @@ const ScriptCState::SymbolTable_t * ScriptCState::lookupSymbol(const char *sym)
}
return NULL;
}
+
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 15426bc33f9f..4047049a8ae5 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -32,8 +32,8 @@
using namespace android;
using namespace android::renderscript;
-#define GET_TLS() Context::ScriptTLSStruct * tls = \
- (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+#define GET_TLS() ScriptTLSStruct * tls = \
+ (ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
Context * rsc = tls->mContext; \
ScriptC * sc = (ScriptC *) tls->mScript
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
new file mode 100644
index 000000000000..17983ce76484
--- /dev/null
+++ b/libs/rs/rs_hal.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RS_HAL_H
+#define RS_HAL_H
+
+#include <RenderScriptDefines.h>
+
+namespace android {
+namespace renderscript {
+
+class Context;
+class ObjectBase;
+class Element;
+class Type;
+class Allocation;
+class Script;
+class ScriptC;
+
+
+typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
+
+typedef struct ScriptTLSStructRec {
+ Context * mContext;
+ Script * mScript;
+} ScriptTLSStruct;
+
+
+/**
+ * Script management functions
+ */
+typedef struct {
+ void (*shutdownDriver)(Context *);
+ void (*getVersion)(unsigned int *major, unsigned int *minor);
+ void (*setPriority)(const Context *, int32_t priority);
+
+
+
+ struct {
+ bool (*scriptInit)(const Context *rsc, ScriptC *s,
+ char const *resName,
+ char const *cacheDir,
+ uint8_t const *bitcode,
+ size_t bitcodeSize,
+ uint32_t flags,
+ RsHalSymbolLookupFunc lookupFunc);
+
+ void (*invokeFunction)(const Context *rsc, Script *s,
+ uint32_t slot,
+ const void *params,
+ size_t paramLength);
+ int (*invokeRoot)(const Context *rsc, Script *s);
+ void (*invokeForEach)(const Context *rsc,
+ Script *s,
+ const Allocation * ain,
+ Allocation * aout,
+ const void * usr,
+ uint32_t usrLen,
+ const RsScriptCall *sc);
+ void (*invokeInit)(const Context *rsc, Script *s);
+
+ void (*setGlobalVar)(const Context *rsc, const Script *s,
+ uint32_t slot,
+ void *data,
+ size_t dataLength);
+ void (*setGlobalBind)(const Context *rsc, const Script *s,
+ uint32_t slot,
+ void *data);
+ void (*setGlobalObj)(const Context *rsc, const Script *s,
+ uint32_t slot,
+ ObjectBase *data);
+
+ void (*destroy)(const Context *rsc, Script *s);
+ } script;
+
+
+
+} RsdHalFunctions;
+
+void rsiSetObject(ObjectBase **vdst, ObjectBase * vsrc);
+void rsiClearObject(ObjectBase **vdst);
+bool rsiIsObject(const ObjectBase *vdst);
+
+}
+}
+
+
+bool rsdHalInit(android::renderscript::Context *, uint32_t version_major, uint32_t version_minor);
+
+#endif
+
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
index 4a0faf06a12c..267e3edf44e3 100644
--- a/libs/surfaceflinger_client/Android.mk
+++ b/libs/surfaceflinger_client/Android.mk
@@ -1,22 +1,9 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
- ISurfaceComposer.cpp \
- ISurface.cpp \
- ISurfaceComposerClient.cpp \
- IGraphicBufferAlloc.cpp \
- LayerState.cpp \
- SharedBufferStack.cpp \
- Surface.cpp \
- SurfaceComposerClient.cpp
+LOCAL_SRC_FILES:=
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libbinder \
- libhardware \
- libui
+LOCAL_SHARED_LIBRARIES :=
LOCAL_MODULE:= libsurfaceflinger_client
diff --git a/libs/surfaceflinger_client/tests/Android.mk b/libs/surfaceflinger_client/tests/Android.mk
deleted file mode 100644
index 212b8e75919a..000000000000
--- a/libs/surfaceflinger_client/tests/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-# Build the unit tests.
-test_src_files := \
- Surface_test.cpp \
-
-shared_libraries := \
- libcutils \
- libutils \
- libbinder \
- libsurfaceflinger_client \
- libstlport \
-
-static_libraries := \
- libgtest \
- libgtest_main \
-
-c_includes := \
- bionic \
- bionic/libstdc++/include \
- external/gtest/include \
- external/stlport/stlport \
-
-module_tags := tests
-
-$(foreach file,$(test_src_files), \
- $(eval include $(CLEAR_VARS)) \
- $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
- $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
- $(eval LOCAL_C_INCLUDES := $(c_includes)) \
- $(eval LOCAL_SRC_FILES := $(file)) \
- $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
- $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
- $(eval include $(BUILD_EXECUTABLE)) \
-)
-
-# Build the manual test programs.
-include $(call all-subdir-makefiles)
-
-endif
-
-# Include subdirectory makefiles
-# ============================================================
-
-# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
-# team really wants is to build the stuff defined by this makefile.
-ifeq (,$(ONE_SHOT_MAKEFILE))
-include $(call first-makefiles-under,$(LOCAL_PATH))
-endif
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk b/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk
deleted file mode 100644
index d3dfe042850f..000000000000
--- a/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- SharedBufferStackTest.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libcutils \
- libutils \
- libui \
- libsurfaceflinger_client
-
-LOCAL_MODULE:= test-sharedbufferstack
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
deleted file mode 100644
index 7ef59269bade..000000000000
--- a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * 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.
- */
-
-#undef NDEBUG
-
-#include <assert.h>
-#include <cutils/memory.h>
-#include <cutils/log.h>
-#include <utils/Errors.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
-
-using namespace android;
-
-void log(const char* prefix, int *b, size_t num);
-void test0(SharedBufferServer& s, SharedBufferClient& c, size_t num, int* list);
-
-// ----------------------------------------------------------------------------
-
-int main(int argc, char** argv)
-{
- SharedClient client;
- sp<SharedBufferServer> ps(new SharedBufferServer(&client, 0, 4, 0));
- SharedBufferServer& s(*ps);
- SharedBufferClient c(&client, 0, 4, 0);
-
- printf("basic test 0\n");
- int list0[4] = {0, 1, 2, 3};
- test0(s, c, 4, list0);
-
- printf("basic test 1\n");
- int list1[4] = {2, 1, 0, 3};
- test0(s, c, 4, list1);
-
- int b = c.dequeue();
- c.lock(b);
- c.queue(b);
- s.retireAndLock();
-
- printf("basic test 2\n");
- int list2[4] = {1, 2, 3, 0};
- test0(s, c, 4, list2);
-
-
- printf("resize test\n");
- class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
- SharedBufferServer& s;
- virtual status_t operator()(int bufferCount) const {
- return s.resize(bufferCount);
- }
- public:
- SetBufferCountIPC(SharedBufferServer& s) : s(s) { }
- } resize(s);
-
- c.setBufferCount(6, resize);
- int list3[6] = {3, 2, 1, 4, 5, 0};
- test0(s, c, 6, list3);
-
- c.setBufferCount(4, resize);
- int list4[4] = {1, 2, 3, 0};
- test0(s, c, 4, list4);
-
- return 0;
-}
-
-void log(const char* prefix, int *b, size_t num)
-{
- printf("%s: ", prefix);
- for (size_t i=0 ; i<num ; i++) {
- printf("%d ", b[i]);
- }
- printf("\n");
-}
-
-// ----------------------------------------------------------------------------
-
-void test0(
- SharedBufferServer& s,
- SharedBufferClient& c,
- size_t num,
- int* list)
-{
- status_t err;
- int b[num], u[num], r[num];
-
- for (size_t i=0 ; i<num ; i++) {
- b[i] = c.dequeue();
- assert(b[i]==list[i]);
- }
- log("DQ", b, num);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.lock(b[i]);
- assert(err==0);
- }
- log("LK", b, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.queue(b[i]);
- assert(err==0);
- }
- log(" Q", b, num-1);
-
-
- for (size_t i=0 ; i<num-1 ; i++) {
- r[i] = s.retireAndLock();
- assert(r[i]==list[i]);
- err = s.unlock(r[i]);
- assert(err == 0);
- }
- log("RT", r, num-1);
-
- err = c.lock(b[num-1]);
- assert(err == 0);
- log("LK", b+num-1, 1);
-
- err = c.queue(b[num-1]);
- assert(err == 0);
- log(" Q", b+num-1, 1);
-
- r[num-1] = s.retireAndLock();
- assert(r[num-1]==list[num-1]);
- err = s.unlock(r[num-1]);
- assert(err == 0);
- log("RT", r+num-1, 1);
-
- // ------------------------------------
- printf("\n");
-
- for (size_t i=0 ; i<num ; i++) {
- b[i] = c.dequeue();
- assert(b[i]==list[i]);
- }
- log("DQ", b, num);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.lock(b[i]);
- assert(err==0);
- }
- log("LK", b, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- u[i] = b[num-2-i];
- }
- u[num-1] = b[num-1];
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.queue(u[i]);
- assert(err==0);
- }
- log(" Q", u, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- r[i] = s.retireAndLock();
- assert(r[i]==u[i]);
- err = s.unlock(r[i]);
- assert(err == 0);
- }
- log("RT", r, num-1);
-
- err = c.lock(b[num-1]);
- assert(err == 0);
- log("LK", b+num-1, 1);
-
- err = c.queue(b[num-1]);
- assert(err == 0);
- log(" Q", b+num-1, 1);
-
- r[num-1] = s.retireAndLock();
- assert(r[num-1]==list[num-1]);
- err = s.unlock(r[num-1]);
- assert(err == 0);
- log("RT", r+num-1, 1);
-
- // ------------------------------------
- printf("\n");
-
- for (size_t i=0 ; i<num ; i++) {
- b[i] = c.dequeue();
- assert(b[i]==u[i]);
- }
- log("DQ", b, num);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.lock(b[i]);
- assert(err==0);
- }
- log("LK", b, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.queue(b[i]);
- assert(err==0);
- }
- log(" Q", b, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- r[i] = s.retireAndLock();
- assert(r[i]==u[i]);
- err = s.unlock(r[i]);
- assert(err == 0);
- }
- log("RT", r, num-1);
-
- err = c.lock(u[num-1]);
- assert(err == 0);
- log("LK", u+num-1, 1);
-
- err = c.queue(u[num-1]);
- assert(err == 0);
- log(" Q", u+num-1, 1);
-
- r[num-1] = s.retireAndLock();
- assert(r[num-1]==u[num-1]);
- err = s.unlock(r[num-1]);
- assert(err == 0);
- log("RT", r+num-1, 1);
-
- // ------------------------------------
- printf("\n");
-
- b[0] = c.dequeue();
- assert(b[0]==u[0]);
- log("DQ", b, 1);
-
- c.undoDequeue(b[0]);
- assert(err == 0);
- log("UDQ", b, 1);
-
- // ------------------------------------
- printf("\n");
-
- for (size_t i=0 ; i<num ; i++) {
- b[i] = c.dequeue();
- assert(b[i]==u[i]);
- }
- log("DQ", b, num);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.lock(b[i]);
- assert(err==0);
- }
- log("LK", b, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- err = c.queue(b[i]);
- assert(err==0);
- }
- log(" Q", b, num-1);
-
- for (size_t i=0 ; i<num-1 ; i++) {
- r[i] = s.retireAndLock();
- assert(r[i]==u[i]);
- err = s.unlock(r[i]);
- assert(err == 0);
- }
- log("RT", r, num-1);
-
- err = c.lock(u[num-1]);
- assert(err == 0);
- log("LK", u+num-1, 1);
-
- err = c.queue(u[num-1]);
- assert(err == 0);
- log(" Q", u+num-1, 1);
-
- r[num-1] = s.retireAndLock();
- assert(r[num-1]==u[num-1]);
- err = s.unlock(r[num-1]);
- assert(err == 0);
- log("RT", r+num-1, 1);
- printf("\n");
-}
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index e2e698ef7b3b..440ec00e378d 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -7,8 +7,12 @@
//#define LOG_NDEBUG 0
+// Log debug messages about keymap probing.
#define DEBUG_PROBE 0
+// Log debug messages about velocity tracking.
+#define DEBUG_VELOCITY 0
+
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
@@ -329,6 +333,27 @@ void PointerCoords::tooManyAxes(int axis) {
"cannot contain more than %d axis values.", axis, int(MAX_AXES));
}
+bool PointerCoords::operator==(const PointerCoords& other) const {
+ if (bits != other.bits) {
+ return false;
+ }
+ uint32_t count = __builtin_popcountll(bits);
+ for (uint32_t i = 0; i < count; i++) {
+ if (values[i] != other.values[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void PointerCoords::copyFrom(const PointerCoords& other) {
+ bits = other.bits;
+ uint32_t count = __builtin_popcountll(bits);
+ for (uint32_t i = 0; i < count; i++) {
+ values[i] = other.values[i];
+ }
+}
+
// --- MotionEvent ---
@@ -444,6 +469,16 @@ float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
return value;
}
+ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
+ size_t pointerCount = mPointerIds.size();
+ for (size_t i = 0; i < pointerCount; i++) {
+ if (mPointerIds.itemAt(i) == pointerId) {
+ return i;
+ }
+ }
+ return -1;
+}
+
void MotionEvent::offsetLocation(float xOffset, float yOffset) {
mXOffset += xOffset;
mYOffset += yOffset;
@@ -634,6 +669,208 @@ bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
}
+// --- VelocityTracker ---
+
+VelocityTracker::VelocityTracker() {
+ clear();
+}
+
+void VelocityTracker::clear() {
+ mIndex = 0;
+ mMovements[0].idBits.clear();
+ mActivePointerId = -1;
+}
+
+void VelocityTracker::clearPointers(BitSet32 idBits) {
+ BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value);
+ mMovements[mIndex].idBits = remainingIdBits;
+
+ if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) {
+ mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1;
+ }
+}
+
+void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) {
+ if (++mIndex == HISTORY_SIZE) {
+ mIndex = 0;
+ }
+
+ while (idBits.count() > MAX_POINTERS) {
+ idBits.clearBit(idBits.lastMarkedBit());
+ }
+
+ Movement& movement = mMovements[mIndex];
+ movement.eventTime = eventTime;
+ movement.idBits = idBits;
+ uint32_t count = idBits.count();
+ for (uint32_t i = 0; i < count; i++) {
+ movement.positions[i] = positions[i];
+ }
+
+ if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
+ mActivePointerId = count != 0 ? idBits.firstMarkedBit() : -1;
+ }
+
+#if DEBUG_VELOCITY
+ LOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d",
+ eventTime, idBits.value, mActivePointerId);
+ for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) {
+ uint32_t id = iterBits.firstMarkedBit();
+ uint32_t index = idBits.getIndexOfBit(id);
+ iterBits.clearBit(id);
+ float vx, vy;
+ bool available = getVelocity(id, &vx, &vy);
+ if (available) {
+ LOGD(" %d: position (%0.3f, %0.3f), vx=%0.3f, vy=%0.3f, speed=%0.3f",
+ id, positions[index].x, positions[index].y, vx, vy, sqrtf(vx * vx + vy * vy));
+ } else {
+ assert(vx == 0 && vy == 0);
+ LOGD(" %d: position (%0.3f, %0.3f), velocity not available",
+ id, positions[index].x, positions[index].y);
+ }
+ }
+#endif
+}
+
+void VelocityTracker::addMovement(const MotionEvent* event) {
+ int32_t actionMasked = event->getActionMasked();
+
+ switch (actionMasked) {
+ case AMOTION_EVENT_ACTION_DOWN:
+ // Clear all pointers on down before adding the new movement.
+ clear();
+ break;
+ case AMOTION_EVENT_ACTION_POINTER_DOWN: {
+ // Start a new movement trace for a pointer that just went down.
+ // We do this on down instead of on up because the client may want to query the
+ // final velocity for a pointer that just went up.
+ BitSet32 downIdBits;
+ downIdBits.markBit(event->getActionIndex());
+ clearPointers(downIdBits);
+ break;
+ }
+ case AMOTION_EVENT_ACTION_OUTSIDE:
+ case AMOTION_EVENT_ACTION_CANCEL:
+ case AMOTION_EVENT_ACTION_SCROLL:
+ case AMOTION_EVENT_ACTION_UP:
+ case AMOTION_EVENT_ACTION_POINTER_UP:
+ // Ignore these actions because they do not convey any new information about
+ // pointer movement. We also want to preserve the last known velocity of the pointers.
+ // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
+ // of the pointers that went up. ACTION_POINTER_UP does include the new position of
+ // pointers that remained down but we will also receive an ACTION_MOVE with this
+ // information if any of them actually moved. Since we don't know how many pointers
+ // will be going up at once it makes sense to just wait for the following ACTION_MOVE
+ // before adding the movement.
+ return;
+ }
+
+ size_t pointerCount = event->getPointerCount();
+ if (pointerCount > MAX_POINTERS) {
+ pointerCount = MAX_POINTERS;
+ }
+
+ BitSet32 idBits;
+ for (size_t i = 0; i < pointerCount; i++) {
+ idBits.markBit(event->getPointerId(i));
+ }
+
+ nsecs_t eventTime;
+ Position positions[pointerCount];
+
+ size_t historySize = event->getHistorySize();
+ for (size_t h = 0; h < historySize; h++) {
+ eventTime = event->getHistoricalEventTime(h);
+ for (size_t i = 0; i < pointerCount; i++) {
+ positions[i].x = event->getHistoricalX(i, h);
+ positions[i].y = event->getHistoricalY(i, h);
+ }
+ addMovement(eventTime, idBits, positions);
+ }
+
+ eventTime = event->getEventTime();
+ for (size_t i = 0; i < pointerCount; i++) {
+ positions[i].x = event->getX(i);
+ positions[i].y = event->getY(i);
+ }
+ addMovement(eventTime, idBits, positions);
+}
+
+bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const {
+ const Movement& newestMovement = mMovements[mIndex];
+ if (newestMovement.idBits.hasBit(id)) {
+ // Find the oldest sample that contains the pointer and that is not older than MAX_AGE.
+ nsecs_t minTime = newestMovement.eventTime - MAX_AGE;
+ uint32_t oldestIndex = mIndex;
+ uint32_t numTouches = 1;
+ do {
+ uint32_t nextOldestIndex = (oldestIndex == 0 ? HISTORY_SIZE : oldestIndex) - 1;
+ const Movement& nextOldestMovement = mMovements[nextOldestIndex];
+ if (!nextOldestMovement.idBits.hasBit(id)
+ || nextOldestMovement.eventTime < minTime) {
+ break;
+ }
+ oldestIndex = nextOldestIndex;
+ } while (++numTouches < HISTORY_SIZE);
+
+ // Calculate an exponentially weighted moving average of the velocity estimate
+ // at different points in time measured relative to the oldest sample.
+ // This is essentially an IIR filter. Newer samples are weighted more heavily
+ // than older samples. Samples at equal time points are weighted more or less
+ // equally.
+ //
+ // One tricky problem is that the sample data may be poorly conditioned.
+ // Sometimes samples arrive very close together in time which can cause us to
+ // overestimate the velocity at that time point. Most samples might be measured
+ // 16ms apart but some consecutive samples could be only 0.5sm apart because
+ // the hardware or driver reports them irregularly or in bursts.
+ float accumVx = 0;
+ float accumVy = 0;
+ uint32_t index = oldestIndex;
+ uint32_t samplesUsed = 0;
+ const Movement& oldestMovement = mMovements[oldestIndex];
+ const Position& oldestPosition =
+ oldestMovement.positions[oldestMovement.idBits.getIndexOfBit(id)];
+ nsecs_t lastDuration = 0;
+ while (numTouches-- > 1) {
+ if (++index == HISTORY_SIZE) {
+ index = 0;
+ }
+ const Movement& movement = mMovements[index];
+ nsecs_t duration = movement.eventTime - oldestMovement.eventTime;
+
+ // If the duration between samples is small, we may significantly overestimate
+ // the velocity. Consequently, we impose a minimum duration constraint on the
+ // samples that we include in the calculation.
+ if (duration >= MIN_DURATION) {
+ const Position& position = movement.positions[movement.idBits.getIndexOfBit(id)];
+ float scale = 1000000000.0f / duration; // one over time delta in seconds
+ float vx = (position.x - oldestPosition.x) * scale;
+ float vy = (position.y - oldestPosition.y) * scale;
+
+ accumVx = (accumVx * lastDuration + vx * duration) / (duration + lastDuration);
+ accumVy = (accumVy * lastDuration + vy * duration) / (duration + lastDuration);
+
+ lastDuration = duration;
+ samplesUsed += 1;
+ }
+ }
+
+ // Make sure we used at least one sample.
+ if (samplesUsed != 0) {
+ *outVx = accumVx;
+ *outVy = accumVy;
+ return true;
+ }
+ }
+
+ // No data available for this pointer.
+ *outVx = 0;
+ *outVy = 0;
+ return false;
+}
+
+
// --- InputDeviceInfo ---
InputDeviceInfo::InputDeviceInfo() {
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
index 5c57a76f40f4..9d1b8b94ecc2 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/ui/InputTransport.cpp
@@ -406,7 +406,7 @@ status_t InputPublisher::publishMotionEvent(
for (size_t i = 0; i < pointerCount; i++) {
mSharedMessage->motion.pointerIds[i] = pointerIds[i];
- mSharedMessage->motion.sampleData[0].coords[i] = pointerCoords[i];
+ mSharedMessage->motion.sampleData[0].coords[i].copyFrom(pointerCoords[i]);
}
// Cache essential information about the motion event to ensure that a malicious consumer
@@ -475,7 +475,7 @@ status_t InputPublisher::appendMotionSample(
mMotionEventSampleDataTail->eventTime = eventTime;
for (size_t i = 0; i < mMotionEventPointerCount; i++) {
- mMotionEventSampleDataTail->coords[i] = pointerCoords[i];
+ mMotionEventSampleDataTail->coords[i].copyFrom(pointerCoords[i]);
}
mMotionEventSampleDataTail = newTail;
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
index e09e755861dc..6e57d93d8b47 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/utils/AssetManager.cpp
@@ -36,6 +36,7 @@
#include <dirent.h>
#include <errno.h>
#include <assert.h>
+#include <strings.h>
using namespace android;
@@ -1764,4 +1765,3 @@ int AssetManager::ZipSet::getIndex(const String8& zip) const
return mZipPath.size()-1;
}
-
diff --git a/libs/utils/Looper.cpp b/libs/utils/Looper.cpp
index 18f858b4b689..d5dd126065e7 100644
--- a/libs/utils/Looper.cpp
+++ b/libs/utils/Looper.cpp
@@ -218,14 +218,10 @@ int Looper::pollInner(int timeoutMillis) {
// Adjust the timeout based on when the next message is due.
if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- if (mNextMessageUptime <= now) {
- timeoutMillis = 0;
- } else {
- uint64_t delay = (mNextMessageUptime - now + 999999LL) / 1000000LL;
- if (delay < INT_MAX
- && (timeoutMillis < 0 || int(delay) < timeoutMillis)) {
- timeoutMillis = int(delay);
- }
+ int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
+ if (messageTimeoutMillis >= 0
+ && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
+ timeoutMillis = messageTimeoutMillis;
}
#if DEBUG_POLL_AND_WAKE
LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
@@ -444,12 +440,11 @@ int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outDat
return result;
}
- nsecs_t timeoutNanos = endTime - systemTime(SYSTEM_TIME_MONOTONIC);
- if (timeoutNanos <= 0) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
+ if (timeoutMillis == 0) {
return ALOOPER_POLL_TIMEOUT;
}
-
- timeoutMillis = int(nanoseconds_to_milliseconds(timeoutNanos + 999999LL));
}
}
}
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
index 784f035dc03a..64a29f58776a 100644
--- a/libs/utils/Timers.cpp
+++ b/libs/utils/Timers.cpp
@@ -26,6 +26,7 @@
#include <sys/time.h>
#include <time.h>
#include <errno.h>
+#include <limits.h>
#ifdef HAVE_WIN32_THREADS
#include <windows.h>
@@ -53,6 +54,23 @@ nsecs_t systemTime(int clock)
#endif
}
+int toMillisecondTimeoutDelay(nsecs_t referenceTime, nsecs_t timeoutTime)
+{
+ int timeoutDelayMillis;
+ if (timeoutTime > referenceTime) {
+ uint64_t timeoutDelay = uint64_t(timeoutTime - referenceTime);
+ if (timeoutDelay > uint64_t((INT_MAX - 1) * 1000000LL)) {
+ timeoutDelayMillis = -1;
+ } else {
+ timeoutDelayMillis = (timeoutDelay + 999999LL) / 1000000LL;
+ }
+ } else {
+ timeoutDelayMillis = 0;
+ }
+ return timeoutDelayMillis;
+}
+
+
/*
* ===========================================================================
* DurationTimer