summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/camera/Camera.cpp5
-rw-r--r--libs/camera/CameraParameters.cpp2
-rw-r--r--libs/camera/ICameraClient.cpp17
-rw-r--r--libs/gui/ISurfaceTexture.cpp13
-rw-r--r--libs/gui/Surface.cpp5
-rw-r--r--libs/gui/SurfaceTexture.cpp162
-rw-r--r--libs/gui/SurfaceTextureClient.cpp13
-rw-r--r--libs/hwui/Caches.cpp1
-rw-r--r--libs/hwui/Debug.h3
-rw-r--r--libs/hwui/Extensions.h28
-rw-r--r--libs/hwui/FontRenderer.cpp21
-rw-r--r--libs/hwui/FontRenderer.h7
-rw-r--r--libs/hwui/GradientCache.cpp40
-rw-r--r--libs/hwui/GradientCache.h105
-rw-r--r--libs/hwui/Layer.h9
-rw-r--r--libs/hwui/LayerCache.h4
-rw-r--r--libs/hwui/Matrix.cpp23
-rw-r--r--libs/hwui/Matrix.h2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp25
-rw-r--r--libs/hwui/OpenGLRenderer.h1
-rw-r--r--libs/hwui/PatchCache.h7
-rw-r--r--libs/hwui/PathCache.h4
-rw-r--r--libs/hwui/ProgramCache.cpp28
-rw-r--r--libs/hwui/ResourceCache.cpp6
-rw-r--r--libs/hwui/ShapeCache.h40
-rw-r--r--libs/hwui/SkiaShader.cpp17
-rw-r--r--libs/rs/RenderScript.h4
-rw-r--r--libs/rs/driver/rsdBcc.cpp115
-rw-r--r--libs/rs/driver/rsdProgram.cpp3
-rw-r--r--libs/rs/driver/rsdRuntimeStubs.cpp53
-rw-r--r--libs/rs/driver/rsdShader.cpp18
-rw-r--r--libs/rs/driver/rsdShader.h1
-rw-r--r--libs/rs/rs.spec7
-rw-r--r--libs/rs/rsAllocation.cpp23
-rw-r--r--libs/rs/rsAllocation.h10
-rw-r--r--libs/rs/rsComponent.cpp30
-rw-r--r--libs/rs/rsComponent.h2
-rw-r--r--libs/rs/rsContext.cpp39
-rw-r--r--libs/rs/rsContext.h4
-rw-r--r--libs/rs/rsElement.cpp178
-rw-r--r--libs/rs/rsElement.h53
-rw-r--r--libs/rs/rsFileA3D.cpp4
-rw-r--r--libs/rs/rsFont.cpp72
-rw-r--r--libs/rs/rsFont.h1
-rw-r--r--libs/rs/rsLocklessFifo.cpp14
-rw-r--r--libs/rs/rsLocklessFifo.h4
-rw-r--r--libs/rs/rsObjectBase.h5
-rw-r--r--libs/rs/rsProgram.cpp2
-rw-r--r--libs/rs/rsProgramFragment.cpp14
-rw-r--r--libs/rs/rsProgramRaster.cpp59
-rw-r--r--libs/rs/rsProgramRaster.h28
-rw-r--r--libs/rs/rsProgramStore.cpp82
-rw-r--r--libs/rs/rsProgramStore.h25
-rw-r--r--libs/rs/rsProgramVertex.cpp50
-rw-r--r--libs/rs/rsSampler.cpp47
-rw-r--r--libs/rs/rsSampler.h36
-rw-r--r--libs/rs/rsScriptC.cpp29
-rw-r--r--libs/rs/rsScriptC.h7
-rw-r--r--libs/rs/rsSignal.cpp29
-rw-r--r--libs/rs/rsSignal.h5
-rw-r--r--libs/rs/rsThreadIO.cpp16
-rw-r--r--libs/rs/rsThreadIO.h2
-rw-r--r--libs/rs/rsType.cpp48
-rw-r--r--libs/rs/rsType.h20
-rw-r--r--libs/rs/rs_hal.h13
-rw-r--r--libs/rs/scriptc/rs_allocation.rsh144
-rw-r--r--libs/rs/scriptc/rs_atomic.rsh248
-rw-r--r--libs/rs/scriptc/rs_cl.rsh25
-rw-r--r--libs/rs/scriptc/rs_core.rsh653
-rw-r--r--libs/rs/scriptc/rs_debug.rsh123
-rw-r--r--libs/rs/scriptc/rs_graphics.rsh113
-rw-r--r--libs/rs/scriptc/rs_math.rsh603
-rw-r--r--libs/rs/scriptc/rs_matrix.rsh378
-rw-r--r--libs/rs/scriptc/rs_object.rsh205
-rw-r--r--libs/rs/scriptc/rs_quaternion.rsh257
-rw-r--r--libs/rs/scriptc/rs_time.rsh22
-rw-r--r--libs/rs/scriptc/rs_types.rsh299
-rw-r--r--libs/ui/EGLUtils.cpp58
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp2
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp22
-rw-r--r--libs/ui/Input.cpp46
-rw-r--r--libs/ui/tests/InputEvent_test.cpp16
-rw-r--r--libs/utils/RefBase.cpp83
83 files changed, 3284 insertions, 1753 deletions
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 3c00db556022..7ac3cc1df718 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -360,7 +360,8 @@ void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
}
// callback from camera service when frame or image is ready
-void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
+void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata)
{
sp<CameraListener> listener;
{
@@ -368,7 +369,7 @@ void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
listener = mListener;
}
if (listener != NULL) {
- listener->postData(msgType, dataPtr);
+ listener->postData(msgType, dataPtr, metadata);
}
}
diff --git a/libs/camera/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
index d8fef09f04c0..51b96c1fe9dd 100644
--- a/libs/camera/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -86,6 +86,7 @@ const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
+const char CameraParameters::KEY_RECORDING_HINT[] = "recording-hint";
const char CameraParameters::TRUE[] = "true";
const char CameraParameters::FALSE[] = "false";
@@ -150,6 +151,7 @@ const char CameraParameters::PIXEL_FORMAT_YUV420P[] = "yuv420p";
const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565";
const char CameraParameters::PIXEL_FORMAT_RGBA8888[] = "rgba8888";
const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg";
+const char CameraParameters::PIXEL_FORMAT_BAYER_RGGB[] = "bayer-rggb";
// Values for focus mode settings.
const char CameraParameters::FOCUS_MODE_AUTO[] = "auto";
diff --git a/libs/camera/ICameraClient.cpp b/libs/camera/ICameraClient.cpp
index cb3bd0c6180f..183429ad8c7b 100644
--- a/libs/camera/ICameraClient.cpp
+++ b/libs/camera/ICameraClient.cpp
@@ -51,13 +51,18 @@ public:
}
// generic data callback from camera service to app with image data
- void dataCallback(int32_t msgType, const sp<IMemory>& imageData)
+ void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
+ camera_frame_metadata_t *metadata)
{
LOGV("dataCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt32(msgType);
data.writeStrongBinder(imageData->asBinder());
+ if (metadata) {
+ data.writeInt32(metadata->number_of_faces);
+ data.write(metadata->faces, sizeof(camera_face_t) * metadata->number_of_faces);
+ }
remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -96,7 +101,15 @@ status_t BnCameraClient::onTransact(
CHECK_INTERFACE(ICameraClient, data, reply);
int32_t msgType = data.readInt32();
sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
- dataCallback(msgType, imageData);
+ camera_frame_metadata_t *metadata = NULL;
+ if (data.dataAvail() > 0) {
+ metadata = new camera_frame_metadata_t;
+ metadata->number_of_faces = data.readInt32();
+ metadata->faces = (camera_face_t *) data.readInplace(
+ sizeof(camera_face_t) * metadata->number_of_faces);
+ }
+ dataCallback(msgType, imageData, metadata);
+ if (metadata) delete metadata;
return NO_ERROR;
} break;
case DATA_CALLBACK_TIMESTAMP: {
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index 55246dc902e5..babd2c07bc63 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -162,11 +162,15 @@ public:
return result;
}
- virtual status_t connect(int api) {
+ virtual status_t connect(int api,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(api);
remote()->transact(CONNECT, data, &reply);
+ *outWidth = reply.readInt32();
+ *outHeight = reply.readInt32();
+ *outTransform = reply.readInt32();
status_t result = reply.readInt32();
return result;
}
@@ -283,7 +287,12 @@ status_t BnSurfaceTexture::onTransact(
case CONNECT: {
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int api = data.readInt32();
- status_t res = connect(api);
+ uint32_t outWidth, outHeight, outTransform;
+ status_t res = connect(api,
+ &outWidth, &outHeight, &outTransform);
+ reply->writeInt32(outWidth);
+ reply->writeInt32(outHeight);
+ reply->writeInt32(outTransform);
reply->writeInt32(res);
return NO_ERROR;
} break;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index ccf98e500c9a..2c702511de51 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -277,6 +277,11 @@ sp<Surface> Surface::readFromParcel(const Parcel& data) {
if (surface == 0) {
surface = new Surface(data, binder);
sCachedSurfaces.add(binder, surface);
+ } else {
+ // The Surface was found in the cache, but we still should clear any
+ // remaining data from the parcel.
+ data.readStrongBinder(); // ISurfaceTexture
+ data.readInt32(); // identity
}
if (surface->mSurface == NULL && surface->getISurfaceTexture() == NULL) {
surface = 0;
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 16755ad98b2e..7ac43431f1d1 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -104,7 +104,7 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode) :
SurfaceTexture::~SurfaceTexture() {
LOGV("SurfaceTexture::~SurfaceTexture");
- freeAllBuffers();
+ freeAllBuffersLocked();
}
status_t SurfaceTexture::setBufferCountServerLocked(int bufferCount) {
@@ -154,7 +154,6 @@ status_t SurfaceTexture::setBufferCount(int bufferCount) {
LOGE("setBufferCount: SurfaceTexture has been abandoned!");
return NO_INIT;
}
-
if (bufferCount > NUM_BUFFER_SLOTS) {
LOGE("setBufferCount: bufferCount larger than slots available");
return BAD_VALUE;
@@ -168,24 +167,24 @@ status_t SurfaceTexture::setBufferCount(int bufferCount) {
}
}
+ const int minBufferSlots = mSynchronousMode ?
+ MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
if (bufferCount == 0) {
- const int minBufferSlots = mSynchronousMode ?
- MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
mClientBufferCount = 0;
bufferCount = (mServerBufferCount >= minBufferSlots) ?
mServerBufferCount : minBufferSlots;
return setBufferCountServerLocked(bufferCount);
}
- // We don't allow the client to set a buffer-count less than
- // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
- if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
+ if (bufferCount < minBufferSlots) {
+ LOGE("setBufferCount: requested buffer count (%d) is less than "
+ "minimum (%d)", bufferCount, minBufferSlots);
return BAD_VALUE;
}
// here we're guaranteed that the client doesn't have dequeued buffers
// and will release all of its buffer references.
- freeAllBuffers();
+ freeAllBuffersLocked();
mBufferCount = bufferCount;
mClientBufferCount = bufferCount;
mCurrentTexture = INVALID_BUFFER_SLOT;
@@ -228,11 +227,6 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage) {
LOGV("SurfaceTexture::dequeueBuffer");
- if (mAbandoned) {
- LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
- return NO_INIT;
- }
-
if ((w && !h) || (!w && h)) {
LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h);
return BAD_VALUE;
@@ -246,10 +240,15 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
int dequeuedCount = 0;
bool tryAgain = true;
while (tryAgain) {
+ if (mAbandoned) {
+ LOGE("dequeueBuffer: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+
// We need to wait for the FIFO to drain if the number of buffer
// needs to change.
//
- // The condition "number of buffer needs to change" is true if
+ // The condition "number of buffers needs to change" is true if
// - the client doesn't care about how many buffers there are
// - AND the actual number of buffer is different from what was
// set in the last setBufferCountServer()
@@ -261,31 +260,24 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
// As long as this condition is true AND the FIFO is not empty, we
// wait on mDequeueCondition.
- int minBufferCountNeeded = mSynchronousMode ?
+ const int minBufferCountNeeded = mSynchronousMode ?
MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
- if (!mClientBufferCount &&
+ const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
((mServerBufferCount != mBufferCount) ||
- (mServerBufferCount < minBufferCountNeeded))) {
+ (mServerBufferCount < minBufferCountNeeded));
+
+ if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
// wait for the FIFO to drain
- while (!mQueue.isEmpty()) {
- mDequeueCondition.wait(mMutex);
- if (mAbandoned) {
- LOGE("dequeueBuffer: SurfaceTexture was abandoned while "
- "blocked!");
- return NO_INIT;
- }
- }
- minBufferCountNeeded = mSynchronousMode ?
- MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
+ mDequeueCondition.wait(mMutex);
+ // NOTE: we continue here because we need to reevaluate our
+ // whole state (eg: we could be abandoned or disconnected)
+ continue;
}
-
- if (!mClientBufferCount &&
- ((mServerBufferCount != mBufferCount) ||
- (mServerBufferCount < minBufferCountNeeded))) {
+ if (numberOfBuffersNeedsToChange) {
// here we're guaranteed that mQueue is empty
- freeAllBuffers();
+ freeAllBuffersLocked();
mBufferCount = mServerBufferCount;
if (mBufferCount < minBufferCountNeeded)
mBufferCount = minBufferCountNeeded;
@@ -414,9 +406,9 @@ status_t SurfaceTexture::setSynchronousMode(bool enabled) {
if (!enabled) {
// going to asynchronous mode, drain the queue
- while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
- mDequeueCondition.wait(mMutex);
- }
+ err = drainQueueLocked();
+ if (err != NO_ERROR)
+ return err;
}
if (mSynchronousMode != enabled) {
@@ -548,7 +540,8 @@ status_t SurfaceTexture::setTransform(uint32_t transform) {
return OK;
}
-status_t SurfaceTexture::connect(int api) {
+status_t SurfaceTexture::connect(int api,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
Mutex::Autolock lock(mMutex);
@@ -569,6 +562,9 @@ status_t SurfaceTexture::connect(int api) {
err = -EINVAL;
} else {
mConnectedApi = api;
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
}
break;
default:
@@ -594,7 +590,9 @@ status_t SurfaceTexture::disconnect(int api) {
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
if (mConnectedApi == api) {
+ drainQueueAndFreeBuffersLocked();
mConnectedApi = NO_CONNECTED_API;
+ mDequeueCondition.signal();
} else {
LOGE("disconnect: connected to another api (cur=%d, req=%d)",
mConnectedApi, api);
@@ -628,6 +626,11 @@ status_t SurfaceTexture::updateTexImage() {
LOGV("SurfaceTexture::updateTexImage");
Mutex::Autolock lock(mMutex);
+ if (mAbandoned) {
+ LOGE("calling updateTexImage() on an abandoned SurfaceTexture");
+ return NO_INIT;
+ }
+
// In asynchronous mode the list is guaranteed to be one buffer
// deep, while in synchronous mode we use the oldest buffer.
if (!mQueue.empty()) {
@@ -638,6 +641,10 @@ status_t SurfaceTexture::updateTexImage() {
EGLImageKHR image = mSlots[buf].mEglImage;
if (image == EGL_NO_IMAGE_KHR) {
EGLDisplay dpy = eglGetCurrentDisplay();
+ if (mSlots[buf].mGraphicBuffer == 0) {
+ LOGE("buffer at slot %d is null", buf);
+ return BAD_VALUE;
+ }
image = createImage(dpy, mSlots[buf].mGraphicBuffer);
mSlots[buf].mEglImage = image;
mSlots[buf].mEglDisplay = dpy;
@@ -827,16 +834,64 @@ void SurfaceTexture::setFrameAvailableListener(
mFrameAvailableListener = listener;
}
-void SurfaceTexture::freeAllBuffers() {
+void SurfaceTexture::freeBufferLocked(int i) {
+ mSlots[i].mGraphicBuffer = 0;
+ mSlots[i].mBufferState = BufferSlot::FREE;
+ if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
+ mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
+ mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+ }
+}
+
+void SurfaceTexture::freeAllBuffersLocked() {
+ LOGW_IF(!mQueue.isEmpty(),
+ "freeAllBuffersLocked called but mQueue is not empty");
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
- mSlots[i].mGraphicBuffer = 0;
- mSlots[i].mBufferState = BufferSlot::FREE;
- if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
- eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
- mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
- mSlots[i].mEglDisplay = EGL_NO_DISPLAY;
+ freeBufferLocked(i);
+ }
+}
+
+void SurfaceTexture::freeAllBuffersExceptHeadLocked() {
+ LOGW_IF(!mQueue.isEmpty(),
+ "freeAllBuffersExceptCurrentLocked called but mQueue is not empty");
+ int head = -1;
+ if (!mQueue.empty()) {
+ Fifo::iterator front(mQueue.begin());
+ head = *front;
+ }
+ for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+ if (i != head) {
+ freeBufferLocked(i);
+ }
+ }
+}
+
+status_t SurfaceTexture::drainQueueLocked() {
+ while (mSynchronousMode && !mQueue.isEmpty()) {
+ mDequeueCondition.wait(mMutex);
+ if (mAbandoned) {
+ LOGE("drainQueueLocked: SurfaceTexture has been abandoned!");
+ return NO_INIT;
+ }
+ if (mConnectedApi == NO_CONNECTED_API) {
+ LOGE("drainQueueLocked: SurfaceTexture is not connected!");
+ return NO_INIT;
}
}
+ return NO_ERROR;
+}
+
+status_t SurfaceTexture::drainQueueAndFreeBuffersLocked() {
+ status_t err = drainQueueLocked();
+ if (err == NO_ERROR) {
+ if (mSynchronousMode) {
+ freeAllBuffersLocked();
+ } else {
+ freeAllBuffersExceptHeadLocked();
+ }
+ }
+ return err;
}
EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
@@ -908,8 +963,10 @@ int SurfaceTexture::query(int what, int* outValue)
void SurfaceTexture::abandon() {
Mutex::Autolock lock(mMutex);
- freeAllBuffers();
+ mQueue.clear();
mAbandoned = true;
+ mCurrentTextureBuf.clear();
+ freeAllBuffersLocked();
mDequeueCondition.signal();
}
@@ -965,13 +1022,24 @@ void SurfaceTexture::dump(String8& result, const char* prefix,
for (int i=0 ; i<mBufferCount ; i++) {
const BufferSlot& slot(mSlots[i]);
snprintf(buffer, SIZE,
- "%s%s[%02d] state=%-8s, crop=[%d,%d,%d,%d], transform=0x%02x, "
- "timestamp=%lld\n",
- prefix, (i==mCurrentTexture)?">":" ", i, stateName(slot.mBufferState),
+ "%s%s[%02d] "
+ "state=%-8s, crop=[%d,%d,%d,%d], "
+ "transform=0x%02x, timestamp=%lld",
+ prefix, (i==mCurrentTexture)?">":" ", i,
+ stateName(slot.mBufferState),
slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, slot.mCrop.bottom,
slot.mTransform, slot.mTimestamp
);
result.append(buffer);
+
+ const sp<GraphicBuffer>& buf(slot.mGraphicBuffer);
+ if (buf != NULL) {
+ snprintf(buffer, SIZE,
+ ", %p [%4ux%4u:%4u,%3X]",
+ buf->handle, buf->width, buf->height, buf->stride, buf->format);
+ result.append(buffer);
+ }
+ result.append("\n");
}
}
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index e6837ea3607e..e91be84c48a6 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -258,10 +258,10 @@ int SurfaceTextureClient::perform(int operation, va_list args)
int res = NO_ERROR;
switch (operation) {
case NATIVE_WINDOW_CONNECT:
- res = dispatchConnect(args);
+ // deprecated. must return NO_ERROR.
break;
case NATIVE_WINDOW_DISCONNECT:
- res = dispatchDisconnect(args);
+ // deprecated. must return NO_ERROR.
break;
case NATIVE_WINDOW_SET_USAGE:
res = dispatchSetUsage(args);
@@ -296,6 +296,12 @@ int SurfaceTextureClient::perform(int operation, va_list args)
case NATIVE_WINDOW_SET_SCALING_MODE:
res = dispatchSetScalingMode(args);
break;
+ case NATIVE_WINDOW_API_CONNECT:
+ res = dispatchConnect(args);
+ break;
+ case NATIVE_WINDOW_API_DISCONNECT:
+ res = dispatchDisconnect(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -379,7 +385,8 @@ int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) {
int SurfaceTextureClient::connect(int api) {
LOGV("SurfaceTextureClient::connect");
Mutex::Autolock lock(mMutex);
- int err = mSurfaceTexture->connect(api);
+ int err = mSurfaceTexture->connect(api,
+ &mDefaultWidth, &mDefaultHeight, &mTransformHint);
if (!err && api == NATIVE_WINDOW_API_CPU) {
mConnectedToCpu = true;
}
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index c5858e93f23b..24ec4e8378ae 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -142,7 +142,6 @@ void Caches::dumpMemoryUsage(String8 &log) {
void Caches::clearGarbage() {
textureCache.clearGarbage();
- gradientCache.clearGarbage();
pathCache.clearGarbage();
Mutex::Autolock _l(mGarbageLock);
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 5db73db9fc35..7cbb39da9ee0 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -20,6 +20,9 @@
// Turn on to check for OpenGL errors on each frame
#define DEBUG_OPENGL 1
+// Turn on to display informations about the GPU
+#define DEBUG_EXTENSIONS 0
+
// Turn on to enable initialization information
#define DEBUG_INIT 0
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index eceb5c1cb0df..38d113000480 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -23,6 +23,8 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include "Debug.h"
+
namespace android {
namespace uirenderer {
@@ -31,15 +33,20 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Debug
-#define DEBUG_EXTENSIONS 0
-
-// Debug
#if DEBUG_EXTENSIONS
#define EXT_LOGD(...) LOGD(__VA_ARGS__)
#else
#define EXT_LOGD(...)
#endif
+// Vendor strings
+
+#define VENDOR_IMG "Imagination Technologies"
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes
+///////////////////////////////////////////////////////////////////////////////
+
class Extensions {
public:
Extensions() {
@@ -58,17 +65,21 @@ public:
} while (head);
mHasNPot = hasExtension("GL_OES_texture_npot");
- mHasDrawPath = hasExtension("GL_NV_draw_path");
- mHasCoverageSample = hasExtension("GL_NV_coverage_sample");
mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
+ const char* vendor = (const char*) glGetString(GL_VENDOR);
+ EXT_LOGD("Vendor: %s", vendor);
+ mNeedsHighpTexCoords = strcmp(vendor, VENDOR_IMG) == 0;
+
+ // We don't need to copy the string, the OpenGL ES spec
+ // guarantees the result of glGetString to point to a
+ // static string as long as our OpenGL context is valid
mExtensions = buffer;
}
inline bool hasNPot() const { return mHasNPot; }
- inline bool hasDrawPath() const { return mHasDrawPath; }
- inline bool hasCoverageSample() const { return mHasCoverageSample; }
inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
+ inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
bool hasExtension(const char* extension) const {
const String8 s(extension);
@@ -85,8 +96,7 @@ private:
const char* mExtensions;
bool mHasNPot;
- bool mHasDrawPath;
- bool mHasCoverageSample;
+ bool mNeedsHighpTexCoords;
bool mHasFramebufferFetch;
}; // class Extensions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 9bf3de81ba93..9acf99be1a15 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -44,9 +44,11 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
Font::Font(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX) :
+ int flags, uint32_t italicStyle, uint32_t scaleX,
+ SkPaint::Style style, uint32_t strokeWidth) :
mState(state), mFontId(fontId), mFontSize(fontSize),
- mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX) {
+ mFlags(flags), mItalicStyle(italicStyle), mScaleX(scaleX),
+ mStyle(style), mStrokeWidth(mStrokeWidth) {
}
@@ -283,19 +285,22 @@ Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph) {
}
Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX) {
+ int flags, uint32_t italicStyle, uint32_t scaleX,
+ SkPaint::Style style, uint32_t strokeWidth) {
Vector<Font*> &activeFonts = state->mActiveFonts;
for (uint32_t i = 0; i < activeFonts.size(); i++) {
Font* font = activeFonts[i];
if (font->mFontId == fontId && font->mFontSize == fontSize &&
font->mFlags == flags && font->mItalicStyle == italicStyle &&
- font->mScaleX == scaleX) {
+ font->mScaleX == scaleX && font->mStyle == style &&
+ (style == SkPaint::kFill_Style || font->mStrokeWidth == strokeWidth)) {
return font;
}
}
- Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle, scaleX);
+ Font* newFont = new Font(state, fontId, fontSize, flags, italicStyle,
+ scaleX, style, strokeWidth);
activeFonts.push(newFont);
return newFont;
}
@@ -690,7 +695,11 @@ void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) {
uint32_t italicStyle = *(uint32_t*) &skewX;
const float scaleXFloat = paint->getTextScaleX();
uint32_t scaleX = *(uint32_t*) &scaleXFloat;
- mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle, scaleX);
+ SkPaint::Style style = paint->getStyle();
+ const float strokeWidthFloat = paint->getStrokeWidth();
+ uint32_t strokeWidth = *(uint32_t*) &strokeWidthFloat;
+ mCurrentFont = Font::create(this, fontId, fontSize, flags, italicStyle,
+ scaleX, style, strokeWidth);
const float maxPrecacheFontSize = 40.0f;
bool isNewFont = currentNumFonts != mActiveFonts.size();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 24ed6fa4756f..1922812b387e 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -82,7 +82,8 @@ public:
* Creates a new font associated with the specified font state.
*/
static Font* create(FontRenderer* state, uint32_t fontId, float fontSize,
- int flags, uint32_t italicStyle, uint32_t scaleX);
+ int flags, uint32_t italicStyle, uint32_t scaleX, SkPaint::Style style,
+ uint32_t strokeWidth);
protected:
friend class FontRenderer;
@@ -128,7 +129,7 @@ protected:
};
Font(FontRenderer* state, uint32_t fontId, float fontSize, int flags, uint32_t italicStyle,
- uint32_t scaleX);
+ uint32_t scaleX, SkPaint::Style style, uint32_t strokeWidth);
// Cache of glyphs
DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
@@ -157,6 +158,8 @@ protected:
int mFlags;
uint32_t mItalicStyle;
uint32_t mScaleX;
+ SkPaint::Style mStyle;
+ uint32_t mStrokeWidth;
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 996acd5bceac..aacf22a19e7e 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -35,7 +35,7 @@ namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
GradientCache::GradientCache():
- mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity),
+ mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) {
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) {
@@ -49,7 +49,7 @@ GradientCache::GradientCache():
}
GradientCache::GradientCache(uint32_t maxByteSize):
- mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity),
+ mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity),
mSize(0), mMaxSize(maxByteSize) {
mCache.setOnEntryRemovedListener(this);
}
@@ -81,9 +81,8 @@ void GradientCache::setMaxSize(uint32_t maxSize) {
// Callbacks
///////////////////////////////////////////////////////////////////////////////
-void GradientCache::operator()(SkShader*& shader, Texture*& texture) {
- // Already locked here
- if (shader) {
+void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) {
+ if (texture) {
const uint32_t size = texture->width * texture->height * 4;
mSize -= size;
}
@@ -98,34 +97,25 @@ void GradientCache::operator()(SkShader*& shader, Texture*& texture) {
// Caching
///////////////////////////////////////////////////////////////////////////////
-Texture* GradientCache::get(SkShader* shader) {
- return mCache.get(shader);
-}
+Texture* GradientCache::get(uint32_t* colors, float* positions,
+ int count, SkShader::TileMode tileMode) {
-void GradientCache::remove(SkShader* shader) {
- mCache.remove(shader);
-}
+ GradientCacheEntry gradient(colors, positions, count, tileMode);
+ Texture* texture = mCache.get(gradient);
-void GradientCache::removeDeferred(SkShader* shader) {
- Mutex::Autolock _l(mLock);
- mGarbage.push(shader);
-}
-
-void GradientCache::clearGarbage() {
- Mutex::Autolock _l(mLock);
- size_t count = mGarbage.size();
- for (size_t i = 0; i < count; i++) {
- mCache.remove(mGarbage.itemAt(i));
+ if (!texture) {
+ texture = addLinearGradient(gradient, colors, positions, count, tileMode);
}
- mGarbage.clear();
+
+ return texture;
}
void GradientCache::clear() {
mCache.clear();
}
-Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors,
- float* positions, int count, SkShader::TileMode tileMode) {
+Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient,
+ uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1024, 1);
bitmap.allocPixels();
@@ -156,7 +146,7 @@ Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors,
generateTexture(&bitmap, texture);
mSize += size;
- mCache.put(shader, texture);
+ mCache.put(gradient, texture);
return texture;
}
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 30da46209800..733985317c7c 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -22,17 +22,85 @@
#include <utils/Vector.h>
#include "Texture.h"
+#include "utils/Compare.h"
#include "utils/GenerationCache.h"
namespace android {
namespace uirenderer {
+struct GradientCacheEntry {
+ GradientCacheEntry() {
+ count = 0;
+ colors = NULL;
+ positions = NULL;
+ tileMode = SkShader::kClamp_TileMode;
+ }
+
+ GradientCacheEntry(uint32_t* colors, float* positions, int count,
+ SkShader::TileMode tileMode) {
+ copy(colors, positions, count, tileMode);
+ }
+
+ GradientCacheEntry(const GradientCacheEntry& entry) {
+ copy(entry.colors, entry.positions, entry.count, entry.tileMode);
+ }
+
+ ~GradientCacheEntry() {
+ delete[] colors;
+ delete[] positions;
+ }
+
+ GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
+ if (this != &entry) {
+ delete[] colors;
+ delete[] positions;
+
+ copy(entry.colors, entry.positions, entry.count, entry.tileMode);
+ }
+
+ return *this;
+ }
+
+ bool operator<(const GradientCacheEntry& r) const {
+ const GradientCacheEntry& rhs = (const GradientCacheEntry&) r;
+ LTE_INT(count) {
+ LTE_INT(tileMode) {
+ int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t));
+ if (result< 0) return true;
+ else if (result == 0) {
+ result = memcmp(positions, rhs.positions, count * sizeof(float));
+ if (result < 0) return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ uint32_t* colors;
+ float* positions;
+ int count;
+ SkShader::TileMode tileMode;
+
+private:
+
+ void copy(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) {
+ this->count = count;
+ this->colors = new uint32_t[count];
+ this->positions = new float[count];
+ this->tileMode = tileMode;
+
+ memcpy(this->colors, colors, count * sizeof(uint32_t));
+ memcpy(this->positions, positions, count * sizeof(float));
+ }
+
+}; // GradientCacheEntry
+
/**
* A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum
* allowed size will also cause the oldest texture to be kicked out.
*/
-class GradientCache: public OnEntryRemoved<SkShader*, Texture*> {
+class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
public:
GradientCache();
GradientCache(uint32_t maxByteSize);
@@ -42,32 +110,13 @@ public:
* Used as a callback when an entry is removed from the cache.
* Do not invoke directly.
*/
- void operator()(SkShader*& shader, Texture*& texture);
+ void operator()(GradientCacheEntry& shader, Texture*& texture);
/**
- * Adds a new linear gradient to the cache. The generated texture is
- * returned.
- */
- Texture* addLinearGradient(SkShader* shader, uint32_t* colors, float* positions,
- int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
- /**
* Returns the texture associated with the specified shader.
*/
- Texture* get(SkShader* shader);
- /**
- * Removes the texture associated with the specified shader.
- * Upon remove the texture is freed.
- */
- void remove(SkShader* shader);
- /**
- * Removes the texture associated with the specified shader. This is meant
- * to be called from threads that are not the EGL context thread.
- */
- void removeDeferred(SkShader* shader);
- /**
- * Process deferred removals.
- */
- void clearGarbage();
+ Texture* get(uint32_t* colors, float* positions,
+ int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
/**
* Clears the cache. This causes all textures to be deleted.
*/
@@ -87,9 +136,17 @@ public:
uint32_t getSize();
private:
+ /**
+ * Adds a new linear gradient to the cache. The generated texture is
+ * returned.
+ */
+ Texture* addLinearGradient(GradientCacheEntry& gradient,
+ uint32_t* colors, float* positions, int count,
+ SkShader::TileMode tileMode = SkShader::kClamp_TileMode);
+
void generateTexture(SkBitmap* bitmap, Texture* texture);
- GenerationCache<SkShader*, Texture*> mCache;
+ GenerationCache<GradientCacheEntry, Texture*> mCache;
uint32_t mSize;
uint32_t mMaxSize;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index dd75497c19a9..a8ae5c6eebd9 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -203,6 +203,10 @@ struct Layer {
return texTransform;
}
+ inline mat4& getTransform() {
+ return transform;
+ }
+
/**
* Bounds of the layer.
*/
@@ -282,6 +286,11 @@ private:
*/
mat4 texTransform;
+ /**
+ * Optional transform.
+ */
+ mat4 transform;
+
}; // struct Layer
}; // namespace uirenderer
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index a0eae592b60f..63bb824c1281 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -119,10 +119,6 @@ private:
mHeight = uint32_t(ceilf(layerHeight / float(LAYER_SIZE)) * LAYER_SIZE);
}
- LayerEntry(const LayerEntry& entry):
- mLayer(entry.mLayer), mWidth(entry.mWidth), mHeight(entry.mHeight) {
- }
-
LayerEntry(Layer* layer):
mLayer(layer), mWidth(layer->getWidth()), mHeight(layer->getHeight()) {
}
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 9fc5131ee931..769c99cf293a 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -51,6 +51,7 @@ void Matrix4::loadIdentity() {
data[kTranslateZ] = 0.0f;
data[kPerspective2] = 1.0f;
+ mIsIdentity = true;
mSimpleMatrix = true;
}
@@ -71,14 +72,21 @@ bool Matrix4::isSimple() {
return mSimpleMatrix;
}
+bool Matrix4::isIdentity() {
+ return mIsIdentity;
+}
+
void Matrix4::load(const float* v) {
memcpy(data, v, sizeof(data));
+ // TODO: Do something smarter here
mSimpleMatrix = false;
+ mIsIdentity = false;
}
void Matrix4::load(const Matrix4& v) {
memcpy(data, v.data, sizeof(data));
mSimpleMatrix = v.mSimpleMatrix;
+ mIsIdentity = v.mIsIdentity;
}
void Matrix4::load(const SkMatrix& v) {
@@ -99,6 +107,7 @@ void Matrix4::load(const SkMatrix& v) {
data[kScaleZ] = 1.0f;
mSimpleMatrix = (v.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask));
+ mIsIdentity = v.isIdentity();
}
void Matrix4::copyTo(SkMatrix& v) const {
@@ -148,6 +157,7 @@ void Matrix4::loadInverse(const Matrix4& v) {
v.data[kSkewX] * v.data[kSkewY]) * scale;
mSimpleMatrix = v.mSimpleMatrix;
+ mIsIdentity = v.mIsIdentity;
}
void Matrix4::copyTo(float* v) const {
@@ -166,20 +176,27 @@ void Matrix4::multiply(float v) {
for (int i = 0; i < 16; i++) {
data[i] *= v;
}
+ mIsIdentity = false;
}
void Matrix4::loadTranslate(float x, float y, float z) {
loadIdentity();
+
data[kTranslateX] = x;
data[kTranslateY] = y;
data[kTranslateZ] = z;
+
+ mIsIdentity = false;
}
void Matrix4::loadScale(float sx, float sy, float sz) {
loadIdentity();
+
data[kScaleX] = sx;
data[kScaleY] = sy;
data[kScaleZ] = sz;
+
+ mIsIdentity = false;
}
void Matrix4::loadSkew(float sx, float sy) {
@@ -198,6 +215,7 @@ void Matrix4::loadSkew(float sx, float sy) {
data[kPerspective2] = 1.0f;
mSimpleMatrix = false;
+ mIsIdentity = false;
}
void Matrix4::loadRotate(float angle, float x, float y, float z) {
@@ -238,6 +256,7 @@ void Matrix4::loadRotate(float angle, float x, float y, float z) {
data[kScaleZ] = z * z * nc + c;
mSimpleMatrix = false;
+ mIsIdentity = false;
}
void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {
@@ -262,16 +281,20 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) {
}
mSimpleMatrix = u.mSimpleMatrix && v.mSimpleMatrix;
+ mIsIdentity = false;
}
void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) {
loadIdentity();
+
data[kScaleX] = 2.0f / (right - left);
data[kScaleY] = 2.0f / (top - bottom);
data[kScaleZ] = -2.0f / (far - near);
data[kTranslateX] = -(right + left) / (right - left);
data[kTranslateY] = -(top + bottom) / (top - bottom);
data[kTranslateZ] = -(far + near) / (far - near);
+
+ mIsIdentity = false;
}
#define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 2fa6ab7757a7..56fd37de813b 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -112,6 +112,7 @@ public:
bool isPureTranslate();
bool isSimple();
+ bool isIdentity();
bool changesBounds();
@@ -128,6 +129,7 @@ public:
private:
bool mSimpleMatrix;
+ bool mIsIdentity;
inline float get(int i, int j) const {
return data[i * 4 + j];
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e67abbd7e17d..a0f806a209ba 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -627,6 +627,12 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
float alpha = layer->getAlpha() / 255.0f;
+ mat4& transform = layer->getTransform();
+ if (!transform.isIdentity()) {
+ save(0);
+ mSnapshot->transform->multiply(transform);
+ }
+
setupDraw();
if (layer->getRenderTarget() == GL_TEXTURE_2D) {
setupDrawWithTexture();
@@ -663,6 +669,10 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
finishDrawTexture();
+
+ if (!transform.isIdentity()) {
+ restore();
+ }
}
void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) {
@@ -924,13 +934,6 @@ void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
mSnapshot->transform->load(*matrix);
}
-const float* OpenGLRenderer::getMatrix() const {
- if (mSnapshot->fbo != 0) {
- return &mSnapshot->transform->data[0];
- }
- return &mIdentity.data[0];
-}
-
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
mSnapshot->transform->copyTo(*matrix);
}
@@ -1489,13 +1492,19 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
const float x = (int) floorf(dstLeft + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(dstTop + mSnapshot->transform->getTranslateY() + 0.5f);
- texture->setFilter(GL_NEAREST, GL_NEAREST, true);
+ GLenum filter = GL_NEAREST;
+ if (u1 > 0.0f || u2 < 1.0f || v1 > 0.0f || v2 < 1.0f) {
+ filter = GL_LINEAR;
+ }
+ texture->setFilter(filter, filter, true);
+
drawTextureMesh(x, y, x + (dstRight - dstLeft), y + (dstBottom - dstTop),
texture->id, alpha / 255.0f, mode, texture->blend,
&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
GL_TRIANGLE_STRIP, gMeshCount, false, true);
} else {
texture->setFilter(GL_LINEAR, GL_LINEAR, true);
+
drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f,
mode, texture->blend, &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
GL_TRIANGLE_STRIP, gMeshCount);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index fa893f02a69d..14b22b39cfdb 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -87,7 +87,6 @@ public:
virtual void scale(float sx, float sy);
virtual void skew(float sx, float sy);
- const float* getMatrix() const;
void getMatrix(SkMatrix* matrix);
virtual void setMatrix(SkMatrix* matrix);
virtual void concatMatrix(SkMatrix* matrix);
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
index 62d0ce190aec..91b603fcc380 100644
--- a/libs/hwui/PatchCache.h
+++ b/libs/hwui/PatchCache.h
@@ -80,13 +80,6 @@ private:
emptyCount(emptyCount), colorKey(colorKey) {
}
- PatchDescription(const PatchDescription& description):
- bitmapWidth(description.bitmapWidth), bitmapHeight(description.bitmapHeight),
- pixelWidth(description.pixelWidth), pixelHeight(description.pixelHeight),
- xCount(description.xCount), yCount(description.yCount),
- emptyCount(description.emptyCount), colorKey(description.colorKey) {
- }
-
bool operator<(const PatchDescription& rhs) const {
LTE_FLOAT(bitmapWidth) {
LTE_FLOAT(bitmapHeight) {
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 7ff8b74810dd..4904a587f6f3 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -41,10 +41,6 @@ struct PathCacheEntry: public ShapeCacheEntry {
path = NULL;
}
- PathCacheEntry(const PathCacheEntry& entry): ShapeCacheEntry(entry) {
- path = entry.path;
- }
-
bool lessThan(const ShapeCacheEntry& r) const {
const PathCacheEntry& rhs = (const PathCacheEntry&) r;
LTE_INT(path) {
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index d419e3eab38c..c2383f4c7256 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -18,6 +18,7 @@
#include <utils/String8.h>
+#include "Caches.h"
#include "ProgramCache.h"
namespace android {
@@ -64,10 +65,18 @@ const char* gVS_Header_Varyings_HasTexture =
const char* gVS_Header_Varyings_IsAA =
"varying float widthProportion;\n"
"varying float lengthProportion;\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_HasBitmap[2] = {
+ // Default precision
+ "varying vec2 outBitmapTexCoords;\n",
+ // High precision
+ "varying highp vec2 outBitmapTexCoords;\n"
+};
+const char* gVS_Header_Varyings_PointHasBitmap[2] = {
+ // Default precision
+ "varying vec2 outPointBitmapTexCoords;\n",
+ // High precision
+ "varying highp vec2 outPointBitmapTexCoords;\n"
+};
const char* gVS_Header_Varyings_HasGradient[3] = {
// Linear
"varying vec2 linear;\n",
@@ -417,9 +426,10 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ int index = Caches::getInstance().extensions.needsHighpTexCoords() ? 1 : 0;
shader.append(description.isPoint ?
- gVS_Header_Varyings_PointHasBitmap :
- gVS_Header_Varyings_HasBitmap);
+ gVS_Header_Varyings_PointHasBitmap[index] :
+ gVS_Header_Varyings_HasBitmap[index]);
}
// Begin the shader
@@ -455,7 +465,6 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
}
String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
- // Set the default precision
String8 shader;
const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
@@ -479,9 +488,10 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
shader.append(gVS_Header_Varyings_HasGradient[description.gradientType]);
}
if (description.hasBitmap) {
+ int index = Caches::getInstance().extensions.needsHighpTexCoords() ? 1 : 0;
shader.append(description.isPoint ?
- gVS_Header_Varyings_PointHasBitmap :
- gVS_Header_Varyings_HasBitmap);
+ gVS_Header_Varyings_PointHasBitmap[index] :
+ gVS_Header_Varyings_HasBitmap[index]);
}
// Uniforms
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index cd2c40506869..ee7398303c0c 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -166,9 +166,6 @@ void ResourceCache::destructor(SkiaShader* resource) {
ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL;
if (ref == NULL) {
// If we're not tracking this resource, just delete it
- if (Caches::hasInstance()) {
- Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader());
- }
delete resource;
return;
}
@@ -220,9 +217,6 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r
break;
case kShader: {
SkiaShader* shader = (SkiaShader*) resource;
- if (Caches::hasInstance()) {
- Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader());
- }
delete shader;
}
break;
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index 33953be5d20d..0660b690a1cd 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -96,12 +96,6 @@ struct ShapeCacheEntry {
pathEffect = NULL;
}
- ShapeCacheEntry(const ShapeCacheEntry& entry):
- shapeType(entry.shapeType), join(entry.join), cap(entry.cap),
- style(entry.style), miter(entry.miter),
- strokeWidth(entry.strokeWidth), pathEffect(entry.pathEffect) {
- }
-
ShapeCacheEntry(ShapeType type, SkPaint* paint) {
shapeType = type;
join = paint->getStrokeJoin();
@@ -167,14 +161,6 @@ struct RoundRectShapeCacheEntry: public ShapeCacheEntry {
mRy = 0;
}
- RoundRectShapeCacheEntry(const RoundRectShapeCacheEntry& entry):
- ShapeCacheEntry(entry) {
- mWidth = entry.mWidth;
- mHeight = entry.mHeight;
- mRx = entry.mRx;
- mRy = entry.mRy;
- }
-
bool lessThan(const ShapeCacheEntry& r) const {
const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r;
LTE_INT(mWidth) {
@@ -206,11 +192,6 @@ struct CircleShapeCacheEntry: public ShapeCacheEntry {
mRadius = 0;
}
- CircleShapeCacheEntry(const CircleShapeCacheEntry& entry):
- ShapeCacheEntry(entry) {
- mRadius = entry.mRadius;
- }
-
bool lessThan(const ShapeCacheEntry& r) const {
const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r;
LTE_INT(mRadius) {
@@ -234,12 +215,6 @@ struct OvalShapeCacheEntry: public ShapeCacheEntry {
mWidth = mHeight = 0;
}
- OvalShapeCacheEntry(const OvalShapeCacheEntry& entry):
- ShapeCacheEntry(entry) {
- mWidth = entry.mWidth;
- mHeight = entry.mHeight;
- }
-
bool lessThan(const ShapeCacheEntry& r) const {
const OvalShapeCacheEntry& rhs = (const OvalShapeCacheEntry&) r;
LTE_INT(mWidth) {
@@ -266,12 +241,6 @@ struct RectShapeCacheEntry: public ShapeCacheEntry {
mWidth = mHeight = 0;
}
- RectShapeCacheEntry(const RectShapeCacheEntry& entry):
- ShapeCacheEntry(entry) {
- mWidth = entry.mWidth;
- mHeight = entry.mHeight;
- }
-
bool lessThan(const ShapeCacheEntry& r) const {
const RectShapeCacheEntry& rhs = (const RectShapeCacheEntry&) r;
LTE_INT(mWidth) {
@@ -306,15 +275,6 @@ struct ArcShapeCacheEntry: public ShapeCacheEntry {
mUseCenter = 0;
}
- ArcShapeCacheEntry(const ArcShapeCacheEntry& entry):
- ShapeCacheEntry(entry) {
- mWidth = entry.mWidth;
- mHeight = entry.mHeight;
- mStartAngle = entry.mStartAngle;
- mSweepAngle = entry.mSweepAngle;
- mUseCenter = entry.mUseCenter;
- }
-
bool lessThan(const ShapeCacheEntry& r) const {
const ArcShapeCacheEntry& rhs = (const ArcShapeCacheEntry&) r;
LTE_INT(mWidth) {
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 1a60dca04248..242829536aaa 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -144,8 +144,11 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
// Uniforms
bindTexture(texture, mWrapS, mWrapT);
- GLenum filter = textureTransform.isPureTranslate() ? GL_NEAREST : GL_LINEAR;
- texture->setFilter(filter, filter);
+ // Assume linear here; we should really check the transform in
+ // ::updateTransforms() but we don't have the texture object
+ // available at that point. The optimization is not worth the
+ // effort for now.
+ texture->setFilter(GL_LINEAR, GL_LINEAR);
glUniform1i(program->getUniform("bitmapSampler"), textureSlot);
glUniformMatrix4fv(program->getUniform("textureTransform"), 1,
@@ -222,10 +225,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
- Texture* texture = mGradientCache->get(mKey);
- if (!texture) {
- texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX);
- }
+ Texture* texture = mGradientCache->get(mColors, mPositions, mCount, mTileX);
mat4 screenSpace;
computeScreenSpaceMatrix(screenSpace, modelView);
@@ -337,10 +337,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi
GLuint textureSlot = (*textureUnit)++;
glActiveTexture(gTextureUnitsMap[textureSlot]);
- Texture* texture = mGradientCache->get(mKey);
- if (!texture) {
- texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount);
- }
+ Texture* texture = mGradientCache->get(mColors, mPositions, mCount);
mat4 screenSpace;
computeScreenSpaceMatrix(screenSpace, modelView);
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 535f713c684c..3ba012353ca7 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -52,8 +52,8 @@ void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **
RsDevice rsDeviceCreate();
void rsDeviceDestroy(RsDevice dev);
void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
-RsContext rsContextCreate(RsDevice dev, uint32_t version);
-RsContext rsContextCreateGL(RsDevice dev, uint32_t version, RsSurfaceConfig sc, uint32_t dpi);
+RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion);
+RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, RsSurfaceConfig sc, uint32_t dpi);
#include "rsgApiFuncDecl.h"
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 0c0aa10ad7ad..176dd182b951 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -19,7 +19,7 @@
#include "rsdBcc.h"
#include "rsdRuntime.h"
-#include <bcinfo/bcinfo.h>
+#include <bcinfo/MetadataExtractor.h>
#include "rsContext.h"
#include "rsScriptC.h"
@@ -40,7 +40,7 @@ struct DrvScript {
BCCScriptRef mBccScript;
- struct BCScriptMetadata *mScriptMetadata;
+ bcinfo::MetadataExtractor *ME;
InvokeFunc_t *mInvokeFunctions;
void ** mFieldAddress;
@@ -71,7 +71,9 @@ bool rsdScriptInit(const Context *rsc,
pthread_mutex_lock(&rsdgInitMutex);
char *cachePath = NULL;
- struct BCScriptMetadata *md = NULL;
+ size_t exportFuncCount = 0;
+ size_t exportVarCount = 0;
+ size_t objectSlotCount = 0;
DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
if (drv == NULL) {
@@ -84,13 +86,13 @@ bool rsdScriptInit(const Context *rsc,
drv->mScriptText = bitcode;
drv->mScriptTextLength = bitcodeSize;
- md = bcinfoGetScriptMetadata((const char*)drv->mScriptText,
- drv->mScriptTextLength, 0);
- if (!md) {
+
+ drv->ME = new bcinfo::MetadataExtractor((const char*)drv->mScriptText,
+ drv->mScriptTextLength);
+ if (!drv->ME->extract()) {
LOGE("bcinfo: failed to read script metadata");
goto error;
}
- drv->mScriptMetadata = md;
//LOGE("mBccScript %p", script->mBccScript);
@@ -112,7 +114,7 @@ bool rsdScriptInit(const Context *rsc,
goto error;
}
- if (bccPrepareExecutableEx(drv->mBccScript, cacheDir, resName, 0) != 0) {
+ if (bccPrepareExecutable(drv->mBccScript, cacheDir, resName, 0) != 0) {
LOGE("bcc: FAILS to prepare executable");
goto error;
}
@@ -122,40 +124,41 @@ bool rsdScriptInit(const Context *rsc,
drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
- if (md->exportFuncCount > 0) {
- drv->mInvokeFunctions = (InvokeFunc_t*) calloc(md->exportFuncCount,
+ exportFuncCount = drv->ME->getExportFuncCount();
+ if (exportFuncCount > 0) {
+ drv->mInvokeFunctions = (InvokeFunc_t*) calloc(exportFuncCount,
sizeof(InvokeFunc_t));
- bccGetExportFuncList(drv->mBccScript,
- md->exportFuncCount,
+ bccGetExportFuncList(drv->mBccScript, exportFuncCount,
(void **) drv->mInvokeFunctions);
} else {
drv->mInvokeFunctions = NULL;
}
- if (md->exportVarCount > 0) {
- drv->mFieldAddress = (void **) calloc(md->exportVarCount,
- sizeof(void*));
- drv->mFieldIsObject = (bool *) calloc(md->exportVarCount, sizeof(bool));
- bccGetExportVarList(drv->mBccScript,
- md->exportVarCount,
+ exportVarCount = drv->ME->getExportVarCount();
+ if (exportVarCount > 0) {
+ drv->mFieldAddress = (void **) calloc(exportVarCount, sizeof(void*));
+ drv->mFieldIsObject = (bool *) calloc(exportVarCount, sizeof(bool));
+ bccGetExportVarList(drv->mBccScript, exportVarCount,
(void **) drv->mFieldAddress);
} else {
drv->mFieldAddress = NULL;
drv->mFieldIsObject = NULL;
}
- if (md->objectSlotCount) {
- for (uint32_t ct=0; ct < md->objectSlotCount; ct++) {
- drv->mFieldIsObject[md->objectSlotList[ct]] = true;
+ objectSlotCount = drv->ME->getObjectSlotCount();
+ if (objectSlotCount > 0) {
+ const uint32_t *objectSlotList = drv->ME->getObjectSlotList();
+ for (uint32_t ct=0; ct < objectSlotCount; ct++) {
+ drv->mFieldIsObject[objectSlotList[ct]] = true;
}
}
// Copy info over to runtime
- script->mHal.info.exportedFunctionCount = md->exportFuncCount;
- script->mHal.info.exportedVariableCount = md->exportVarCount;
- script->mHal.info.exportedPragmaCount = md->pragmaCount;
- script->mHal.info.exportedPragmaKeyList = md->pragmaKeyList;
- script->mHal.info.exportedPragmaValueList = md->pragmaValueList;
+ script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount();
+ script->mHal.info.exportedVariableCount = drv->ME->getExportVarCount();
+ script->mHal.info.exportedPragmaCount = drv->ME->getPragmaCount();
+ script->mHal.info.exportedPragmaKeyList = drv->ME->getPragmaKeyList();
+ script->mHal.info.exportedPragmaValueList = drv->ME->getPragmaValueList();
script->mHal.info.root = drv->mRoot;
pthread_mutex_unlock(&rsdgInitMutex);
@@ -164,6 +167,10 @@ bool rsdScriptInit(const Context *rsc,
error:
pthread_mutex_unlock(&rsdgInitMutex);
+ if (drv->ME) {
+ delete drv->ME;
+ drv->ME = NULL;
+ }
free(drv);
return false;
@@ -175,6 +182,7 @@ typedef struct {
const Allocation * ain;
Allocation * aout;
const void * usr;
+ size_t usrLen;
uint32_t mSliceSize;
volatile int mSliceNum;
@@ -202,6 +210,10 @@ typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint
static void wc_xy(void *usr, uint32_t idx) {
MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+ RsForEachStubParamStruct p;
+ memset(&p, 0, sizeof(p));
+ p.usr = mtls->usr;
+ p.usr_len = mtls->usrLen;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
@@ -214,13 +226,15 @@ static void wc_xy(void *usr, uint32_t idx) {
//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;
+ for (p.y = yStart; p.y < yEnd; p.y++) {
+ uint32_t offset = mtls->dimX * p.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);
+ for (p.x = mtls->xStart; p.x < mtls->xEnd; p.x++) {
+ p.in = xPtrIn;
+ p.out = xPtrOut;
+ ((rs_t)mtls->script->mHal.info.root) (p.in, p.out, p.usr, p.x, p.y, 0, 0);
xPtrIn += mtls->eStrideIn;
xPtrOut += mtls->eStrideOut;
}
@@ -230,6 +244,10 @@ static void wc_xy(void *usr, uint32_t idx) {
static void wc_x(void *usr, uint32_t idx) {
MTLaunchStruct *mtls = (MTLaunchStruct *)usr;
+ RsForEachStubParamStruct p;
+ memset(&p, 0, sizeof(p));
+ p.usr = mtls->usr;
+ p.usr_len = mtls->usrLen;
while (1) {
uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum);
@@ -244,8 +262,10 @@ static void wc_x(void *usr, uint32_t idx) {
//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);
+ for (p.x = xStart; p.x < xEnd; p.x++) {
+ p.in = xPtrIn;
+ p.out = xPtrOut;
+ ((rs_t)mtls->script->mHal.info.root) (p.in, p.out, p.usr, p.x, 0, 0, 0);
xPtrIn += mtls->eStrideIn;
xPtrOut += mtls->eStrideOut;
}
@@ -318,6 +338,7 @@ void rsdScriptInvokeForEach(const Context *rsc,
mtls.aout = aout;
mtls.script = s;
mtls.usr = usr;
+ mtls.usrLen = usrLen;
mtls.mSliceSize = 10;
mtls.mSliceNum = 0;
@@ -344,18 +365,25 @@ void rsdScriptInvokeForEach(const Context *rsc,
//LOGE("launch 1");
} else {
+ RsForEachStubParamStruct p;
+ memset(&p, 0, sizeof(p));
+ p.usr = mtls.usr;
+ p.usr_len = mtls.usrLen;
+
//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;
+ for (p.ar[0] = mtls.arrayStart; p.ar[0] < mtls.arrayEnd; p.ar[0]++) {
+ for (p.z = mtls.zStart; p.z < mtls.zEnd; p.z++) {
+ for (p.y = mtls.yStart; p.y < mtls.yEnd; p.y++) {
+ uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * p.ar[0] +
+ mtls.dimX * mtls.dimY * p.z +
+ mtls.dimX * p.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);
+ for (p.x = mtls.xStart; p.x < mtls.xEnd; p.x++) {
+ p.in = xPtrIn;
+ p.out = xPtrOut;
+ ((rs_t)s->mHal.info.root) (p.in, p.out, p.usr, p.x, p.y, p.z, p.ar[0]);
xPtrIn += mtls.eStrideIn;
xPtrOut += mtls.eStrideOut;
}
@@ -445,10 +473,10 @@ void rsdScriptSetGlobalObj(const Context *dc, const Script *script, uint32_t slo
void rsdScriptDestroy(const Context *dc, Script *script) {
DrvScript *drv = (DrvScript *)script->mHal.drv;
- struct BCScriptMetadata *md = drv->mScriptMetadata;
if (drv->mFieldAddress) {
- for (size_t ct = 0; ct < md->exportVarCount; ct++) {
+ size_t exportVarCount = drv->ME->getExportVarCount();
+ for (size_t ct = 0; ct < exportVarCount; ct++) {
if (drv->mFieldIsObject[ct]) {
// The field address can be NULL if the script-side has
// optimized the corresponding global variable away.
@@ -467,7 +495,8 @@ void rsdScriptDestroy(const Context *dc, Script *script) {
drv->mInvokeFunctions = NULL;
}
- bcinfoReleaseScriptMetadata(&drv->mScriptMetadata);
+ delete drv->ME;
+ drv->ME = NULL;
free(drv);
script->mHal.drv = NULL;
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
index 39b3805f5473..27a66639148b 100644
--- a/libs/rs/driver/rsdProgram.cpp
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -44,6 +44,9 @@ bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv,
static void SyncProgramConstants(const Context *rsc, const Program *p) {
for (uint32_t ct=0; ct < p->mHal.state.texturesCount; ct++) {
const Allocation *a = p->mHal.state.textures[ct].get();
+ if (!a) {
+ continue;
+ }
DrvAllocation *drvAlloc = (DrvAllocation *)a->mHal.drv;
if (drvAlloc->uploadDeferred) {
rsdAllocationSyncAll(rsc, a, RS_ALLOCATION_USAGE_SCRIPT);
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index d8050ac7bdea..90c8928b2ebc 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -42,41 +42,6 @@ using namespace android::renderscript;
// Allocation
//////////////////////////////////////////////////////////////////////////////
-static uint32_t SC_allocGetDimX(Allocation *a) {
- return a->mHal.state.dimensionX;
-}
-
-static uint32_t SC_allocGetDimY(Allocation *a) {
- return a->mHal.state.dimensionY;
-}
-
-static uint32_t SC_allocGetDimZ(Allocation *a) {
- return a->mHal.state.dimensionZ;
-}
-
-static uint32_t SC_allocGetDimLOD(Allocation *a) {
- return a->mHal.state.hasMipmaps;
-}
-
-static uint32_t SC_allocGetDimFaces(Allocation *a) {
- return a->mHal.state.hasFaces;
-}
-
-static const void * SC_getElementAtX(Allocation *a, uint32_t x) {
- const uint8_t *p = (const uint8_t *)a->getPtr();
- return &p[a->mHal.state.elementSizeBytes * x];
-}
-
-static const void * SC_getElementAtXY(Allocation *a, uint32_t x, uint32_t y) {
- const uint8_t *p = (const uint8_t *)a->getPtr();
- return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX)];
-}
-
-static const void * SC_getElementAtXYZ(Allocation *a, uint32_t x, uint32_t y, uint32_t z) {
- const uint8_t *p = (const uint8_t *)a->getPtr();
- return &p[a->mHal.state.elementSizeBytes * (x + y * a->mHal.state.dimensionX +
- z * a->mHal.state.dimensionX * a->mHal.state.dimensionY)];
-}
static void SC_AllocationSyncAll2(Allocation *a, RsAllocationUsageType source) {
GET_TLS();
@@ -115,12 +80,6 @@ static void SC_AllocationCopy2DRange(Allocation *dstAlloc,
}
-const Allocation * SC_getAllocation(const void *ptr) {
- GET_TLS();
- return rsrGetAllocation(rsc, sc, ptr);
-}
-
-
//////////////////////////////////////////////////////////////////////////////
// Context
//////////////////////////////////////////////////////////////////////////////
@@ -599,18 +558,6 @@ static RsdSymbolTable gSyms[] = {
{ "_Z10rsIsObject7rs_font", (void *)&SC_IsObject, true },
// Allocation ops
- { "_Z19rsAllocationGetDimX13rs_allocation", (void *)&SC_allocGetDimX, true },
- { "_Z19rsAllocationGetDimY13rs_allocation", (void *)&SC_allocGetDimY, true },
- { "_Z19rsAllocationGetDimZ13rs_allocation", (void *)&SC_allocGetDimZ, true },
- { "_Z21rsAllocationGetDimLOD13rs_allocation", (void *)&SC_allocGetDimLOD, true },
- { "_Z23rsAllocationGetDimFaces13rs_allocation", (void *)&SC_allocGetDimFaces, true },
-
- { "_Z14rsGetElementAt13rs_allocationj", (void *)&SC_getElementAtX, true },
- { "_Z14rsGetElementAt13rs_allocationjj", (void *)&SC_getElementAtXY, true },
- { "_Z14rsGetElementAt13rs_allocationjjj", (void *)&SC_getElementAtXYZ, true },
-
- { "_Z15rsGetAllocationPKv", (void *)&SC_getAllocation, true },
-
{ "_Z21rsAllocationMarkDirty13rs_allocation", (void *)&SC_AllocationSyncAll, true },
{ "_Z20rsgAllocationSyncAll13rs_allocation", (void *)&SC_AllocationSyncAll, false },
{ "_Z20rsgAllocationSyncAll13rs_allocationj", (void *)&SC_AllocationSyncAll2, false },
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index 15cc4179dcc2..90fe4b237164 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -48,6 +48,7 @@ RsdShader::~RsdShader() {
delete[] mAttribNames;
delete[] mUniformNames;
delete[] mUniformArraySizes;
+ delete[] mTextureTargets;
}
void RsdShader::initMemberVars() {
@@ -59,6 +60,7 @@ void RsdShader::initMemberVars() {
mAttribNames = NULL;
mUniformNames = NULL;
mUniformArraySizes = NULL;
+ mTextureTargets = NULL;
mIsValid = false;
}
@@ -81,6 +83,7 @@ void RsdShader::init() {
mUniformArraySizes[uniformCount] = 1;
uniformCount++;
}
+
}
String8 RsdShader::getGLSLInputString() const {
@@ -141,8 +144,10 @@ void RsdShader::appendTextures() {
for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+ mTextureTargets[ct] = GL_TEXTURE_2D;
} else {
snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
+ mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
}
mShader.append(buf);
}
@@ -400,9 +405,11 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
glActiveTexture(GL_TEXTURE0 + ct);
+ glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
+
if (!mRSProgram->mHal.state.textures[ct].get()) {
- LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
- rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
+ // if nothing is bound, reset to default GL texture
+ glBindTexture(mTextureTargets[ct], 0);
continue;
}
@@ -422,8 +429,6 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
glTexParameteri(drvTex->glTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
rsdGLCheckError(rsc, "ProgramFragment::setup tex env");
}
-
- glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
rsdGLCheckError(rsc, "ProgramFragment::setup uniforms");
}
@@ -516,6 +521,11 @@ void RsdShader::initAttribAndUniformArray() {
mUniformNames = new String8[mUniformCount];
mUniformArraySizes = new uint32_t[mUniformCount];
}
+
+ mTextureCount = mRSProgram->mHal.state.texturesCount;
+ if (mTextureCount) {
+ mTextureTargets = new uint32_t[mTextureCount];
+ }
}
void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) {
diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h
index 63c4231695de..3f0d6eae909e 100644
--- a/libs/rs/driver/rsdShader.h
+++ b/libs/rs/driver/rsdShader.h
@@ -84,6 +84,7 @@ protected:
uint32_t mType;
uint32_t mTextureCount;
+ uint32_t *mTextureTargets;
uint32_t mAttribCount;
uint32_t mUniformCount;
android::String8 *mAttribNames;
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 0dea97100d35..f27758249a5d 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -127,6 +127,7 @@ ObjDestroy {
}
ElementCreate {
+ direct
param RsDataType mType
param RsDataKind mKind
param bool mNormalized
@@ -135,6 +136,7 @@ ElementCreate {
}
ElementCreate2 {
+ direct
param const RsElement * elements
param const char ** names
param const uint32_t * arraySize
@@ -226,6 +228,7 @@ AllocationCopy2DRange {
}
SamplerCreate {
+ direct
param RsSamplerValue magFilter
param RsSamplerValue minFilter
param RsSamplerValue wrapS
@@ -311,6 +314,7 @@ ScriptCCreate {
ProgramStoreCreate {
+ direct
param bool colorMaskR
param bool colorMaskG
param bool colorMaskB
@@ -324,6 +328,7 @@ ProgramStoreCreate {
}
ProgramRasterCreate {
+ direct
param bool pointSmooth
param bool lineSmooth
param bool pointSprite
@@ -352,12 +357,14 @@ ProgramBindSampler {
}
ProgramFragmentCreate {
+ direct
param const char * shaderText
param const uint32_t * params
ret RsProgramFragment
}
ProgramVertexCreate {
+ direct
param const char * shaderText
param const uint32_t * params
ret RsProgramVertex
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index f3e0c0a75291..a366d4985a48 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -58,6 +58,19 @@ void Allocation::updateCache() {
}
Allocation::~Allocation() {
+ if (mHal.state.hasReferences &&
+ (mHal.state.hasFaces || mHal.state.hasMipmaps)) {
+ LOGE("Cube/mip allocation with references unsupported, memory not cleaned up!");
+ }
+
+ uint32_t elemCount = mHal.state.dimensionX;
+ if (mHal.state.dimensionY > 1) {
+ elemCount *= mHal.state.dimensionY;
+ }
+ if (mHal.state.dimensionZ > 1) {
+ elemCount *= mHal.state.dimensionZ;
+ }
+ decRefs(getPtr(), elemCount, 0);
mRSC->mHal.funcs.allocation.destroy(mRSC, this);
}
@@ -239,6 +252,7 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
alloc->setName(name.string(), name.size());
+ type->decUserRef();
uint32_t count = dataSize / type->getElementSizeBytes();
@@ -270,6 +284,9 @@ 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 {
+ if (!mHal.state.hasReferences || !getIsScript()) {
+ return;
+ }
const uint8_t *p = static_cast<const uint8_t *>(ptr);
const Element *e = mHal.state.type->getElement();
uint32_t stride = e->getSizeBytes();
@@ -291,12 +308,12 @@ void Allocation::resize1D(Context *rsc, uint32_t dimX) {
return;
}
- Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
+ ObjectBaseRef<Type> t = mHal.state.type->cloneAndResize1D(rsc, dimX);
if (dimX < oldDimX) {
decRefs(getPtr(), oldDimX - dimX, dimX);
}
- rsc->mHal.funcs.allocation.resize(rsc, this, t, mHal.state.hasReferences);
- mHal.state.type.set(t);
+ rsc->mHal.funcs.allocation.resize(rsc, this, t.get(), mHal.state.hasReferences);
+ mHal.state.type.set(t.get());
updateCache();
}
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index f538dd13bf99..f2589c0b07ef 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -25,8 +25,16 @@ namespace renderscript {
class Program;
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
class Allocation : public ObjectBase {
- // The graphics equilivent of malloc. The allocation contains a structure of elements.
+ // The graphics equivalent of malloc. The allocation contains a structure of elements.
public:
struct Hal {
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index e65febb4d464..ce06306a1ef0 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -176,36 +176,6 @@ bool Component::isReference() const {
return (mType >= RS_TYPE_ELEMENT);
}
-String8 Component::getGLSLType() const {
- if (mType == RS_TYPE_SIGNED_32) {
- switch (mVectorSize) {
- case 1: return String8("int");
- case 2: return String8("ivec2");
- case 3: return String8("ivec3");
- case 4: return String8("ivec4");
- }
- }
- if (mType == RS_TYPE_FLOAT_32) {
- switch (mVectorSize) {
- case 1: return String8("float");
- case 2: return String8("vec2");
- case 3: return String8("vec3");
- case 4: return String8("vec4");
- }
- }
- if ((mType == RS_TYPE_MATRIX_4X4) && (mVectorSize == 1)) {
- return String8("mat4");
- }
- if ((mType == RS_TYPE_MATRIX_3X3) && (mVectorSize == 1)) {
- return String8("mat3");
- }
- if ((mType == RS_TYPE_MATRIX_2X2) && (mVectorSize == 1)) {
- return String8("mat2");
- }
- return String8();
-}
-
-
static const char * gTypeBasicStrings[] = {
"NONE",
"F16",
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index a448f0e8f495..6ddc990b2486 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -32,10 +32,8 @@ public:
void set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize=1);
- String8 getGLSLType() const;
void dumpLOGV(const char *prefix) const;
-
RsDataType getType() const {return mType;}
RsDataKind getKind() const {return mKind;}
bool getIsNormalized() const {return mNormalized;}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index decd9f1826a9..f65dd4723a81 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -240,25 +240,38 @@ void * Context::threadProc(void *vrsc) {
rsc->setProgramStore(NULL);
rsc->mStateFont.init(rsc);
rsc->setFont(NULL);
+ rsc->mStateSampler.init(rsc);
rsc->mFBOCache.init(rsc);
}
rsc->mRunning = true;
bool mDraw = true;
+ bool doWait = true;
+
+ uint64_t targetTime = rsc->getTime();
while (!rsc->mExit) {
- mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
+ uint64_t waitTime = 0;
+ uint64_t now = rsc->getTime();
+ if (now < targetTime) {
+ waitTime = targetTime - now;
+ } else {
+ doWait = false;
+ }
+
+ mDraw |= rsc->mIO.playCoreCommands(rsc, doWait, waitTime);
mDraw &= (rsc->mRootScript.get() != NULL);
mDraw &= rsc->mHasSurface;
- uint32_t targetTime = 0;
if (mDraw && rsc->mIsGraphicsContext) {
- targetTime = rsc->runRootScript();
+ uint64_t delay = rsc->runRootScript() * 1000000;
+ targetTime = rsc->getTime() + delay;
+ doWait = delay != 0;
if (rsc->props.mLogVisual) {
rsc->displayDebugStats();
}
- mDraw = targetTime && !rsc->mPaused;
+ mDraw = !rsc->mPaused;
rsc->timerSet(RS_TIMER_CLEAR_SWAP);
rsc->mHal.funcs.swap(rsc);
rsc->timerFrame();
@@ -266,12 +279,6 @@ void * Context::threadProc(void *vrsc) {
rsc->timerPrint();
rsc->timerReset();
}
- if (targetTime > 1) {
- int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
- if (t > 0) {
- usleep(t);
- }
- }
}
LOGV("%p, RS Thread exiting", rsc);
@@ -301,6 +308,7 @@ void Context::destroyWorkerThreadResources() {
mStateFragment.deinit(this);
mStateFragmentStore.deinit(this);
mStateFont.deinit(this);
+ mStateSampler.deinit(this);
mFBOCache.deinit(this);
}
//LOGV("destroyWorkerThreadResources 2");
@@ -333,6 +341,7 @@ Context::Context() {
mPaused = false;
mObjHead = NULL;
mError = RS_ERROR_NONE;
+ mTargetSdkVersion = 14;
mDPI = 96;
mIsContextLite = false;
}
@@ -678,19 +687,25 @@ void rsi_ContextDeinitToClient(Context *rsc) {
}
}
-RsContext rsContextCreate(RsDevice vdev, uint32_t version) {
+RsContext rsContextCreate(RsDevice vdev, uint32_t version,
+ uint32_t sdkVersion) {
LOGV("rsContextCreate %p", vdev);
Device * dev = static_cast<Device *>(vdev);
Context *rsc = Context::createContext(dev, NULL);
+ if (rsc) {
+ rsc->setTargetSdkVersion(sdkVersion);
+ }
return rsc;
}
RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
- RsSurfaceConfig sc, uint32_t dpi) {
+ uint32_t sdkVersion, RsSurfaceConfig sc,
+ uint32_t dpi) {
LOGV("rsContextCreateGL %p", vdev);
Device * dev = static_cast<Device *>(vdev);
Context *rsc = Context::createContext(dev, &sc);
if (rsc) {
+ rsc->setTargetSdkVersion(sdkVersion);
rsc->setDPI(dpi);
}
LOGV("rsContextCreateGL ret %p ", rsc);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 309fe9532bba..3c7a3d236eac 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -199,9 +199,13 @@ public:
uint32_t getDPI() const {return mDPI;}
void setDPI(uint32_t dpi) {mDPI = dpi;}
+ uint32_t getTargetSdkVersion() const {return mTargetSdkVersion;}
+ void setTargetSdkVersion(uint32_t sdkVer) {mTargetSdkVersion = sdkVer;}
+
Device *mDev;
protected:
+ uint32_t mTargetSdkVersion;
uint32_t mDPI;
uint32_t mWidth;
uint32_t mHeight;
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index b77b18a0b686..36bbdf05a48c 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -29,13 +29,16 @@ Element::Element(Context *rsc) : ObjectBase(rsc) {
}
Element::~Element() {
+ clear();
+}
+
+void Element::preDestroy() const {
for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
if (mRSC->mStateElement.mElements[ct] == this) {
mRSC->mStateElement.mElements.removeAt(ct);
break;
}
}
- clear();
}
void Element::clear() {
@@ -60,6 +63,7 @@ size_t Element::getSizeBits() const {
void Element::dumpLOGV(const char *prefix) const {
ObjectBase::dumpLOGV(prefix);
LOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
+ mComponent.dumpLOGV(prefix);
for (uint32_t ct = 0; ct < mFieldCount; ct++) {
LOGV("%s Element field index: %u ------------------", prefix, ct);
LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
@@ -97,60 +101,46 @@ Element *Element::createFromStream(Context *rsc, IStream *stream) {
String8 name;
stream->loadString(&name);
- Element *elem = new Element(rsc);
- elem->mComponent.loadFromStream(stream);
-
- elem->mFieldCount = stream->loadU32();
- if (elem->mFieldCount) {
- elem->mFields = new ElementField_t [elem->mFieldCount];
- for (uint32_t ct = 0; ct < elem->mFieldCount; ct ++) {
- stream->loadString(&elem->mFields[ct].name);
- elem->mFields[ct].arraySize = stream->loadU32();
- Element *fieldElem = Element::createFromStream(rsc, stream);
- elem->mFields[ct].e.set(fieldElem);
- }
- }
+ Component component;
+ component.loadFromStream(stream);
- // We need to check if this already exists
- for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
- Element *ee = rsc->mStateElement.mElements[ct];
- if (ee->isEqual(elem)) {
- ObjectBase::checkDelete(elem);
- ee->incUserRef();
- return ee;
- }
+ uint32_t fieldCount = stream->loadU32();
+ if (!fieldCount) {
+ return (Element *)Element::create(rsc,
+ component.getType(),
+ component.getKind(),
+ component.getIsNormalized(),
+ component.getVectorSize());;
}
- elem->compute();
- rsc->mStateElement.mElements.push(elem);
- return elem;
-}
-
-bool Element::isEqual(const Element *other) const {
- if (other == NULL) {
- return false;
+ const Element **subElems = new const Element *[fieldCount];
+ const char **subElemNames = new const char *[fieldCount];
+ size_t *subElemNamesLengths = new size_t[fieldCount];
+ uint32_t *arraySizes = new uint32_t[fieldCount];
+
+ String8 elemName;
+ for (uint32_t ct = 0; ct < fieldCount; ct ++) {
+ stream->loadString(&elemName);
+ subElemNamesLengths[ct] = elemName.length();
+ char *tmpName = new char[subElemNamesLengths[ct]];
+ memcpy(tmpName, elemName.string(), subElemNamesLengths[ct]);
+ subElemNames[ct] = tmpName;
+ arraySizes[ct] = stream->loadU32();
+ subElems[ct] = Element::createFromStream(rsc, stream);
}
- if (!other->getFieldCount() && !mFieldCount) {
- if ((other->getType() == getType()) &&
- (other->getKind() == getKind()) &&
- (other->getComponent().getIsNormalized() == getComponent().getIsNormalized()) &&
- (other->getComponent().getVectorSize() == getComponent().getVectorSize())) {
- return true;
- }
- return false;
- }
- if (other->getFieldCount() == mFieldCount) {
- for (uint32_t i=0; i < mFieldCount; i++) {
- if ((!other->mFields[i].e->isEqual(mFields[i].e.get())) ||
- (other->mFields[i].name.length() != mFields[i].name.length()) ||
- (other->mFields[i].name != mFields[i].name) ||
- (other->mFields[i].arraySize != mFields[i].arraySize)) {
- return false;
- }
- }
- return true;
+
+ const Element *elem = Element::create(rsc, fieldCount, subElems, subElemNames,
+ subElemNamesLengths, arraySizes);
+ for (uint32_t ct = 0; ct < fieldCount; ct ++) {
+ delete [] subElemNames[ct];
+ subElems[ct]->decUserRef();
}
- return false;
+ delete[] subElems;
+ delete[] subElemNames;
+ delete[] subElemNamesLengths;
+ delete[] arraySizes;
+
+ return (Element *)elem;
}
void Element::compute() {
@@ -172,9 +162,11 @@ void Element::compute() {
}
-const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
+ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
bool isNorm, uint32_t vecSize) {
+ ObjectBaseRef<const Element> returnRef;
// Look for an existing match.
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
const Element *ee = rsc->mStateElement.mElements[ct];
if (!ee->getFieldCount() &&
@@ -183,21 +175,31 @@ const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
(ee->getComponent().getIsNormalized() == isNorm) &&
(ee->getComponent().getVectorSize() == vecSize)) {
// Match
- ee->incUserRef();
+ returnRef.set(ee);
+ ObjectBase::asyncUnlock();
return ee;
}
}
+ ObjectBase::asyncUnlock();
Element *e = new Element(rsc);
+ returnRef.set(e);
e->mComponent.set(dt, dk, isNorm, vecSize);
e->compute();
+
+ ObjectBase::asyncLock();
rsc->mStateElement.mElements.push(e);
- return e;
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
}
-const Element * Element::create(Context *rsc, size_t count, const Element **ein,
+ObjectBaseRef<const Element> Element::createRef(Context *rsc, size_t count, const Element **ein,
const char **nin, const size_t * lengths, const uint32_t *asin) {
+
+ ObjectBaseRef<const Element> returnRef;
// Look for an existing match.
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
const Element *ee = rsc->mStateElement.mElements[ct];
if (ee->getFieldCount() == count) {
@@ -212,13 +214,16 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein,
}
}
if (match) {
- ee->incUserRef();
- return ee;
+ returnRef.set(ee);
+ ObjectBase::asyncUnlock();
+ return returnRef;
}
}
}
+ ObjectBase::asyncUnlock();
Element *e = new Element(rsc);
+ returnRef.set(e);
e->mFields = new ElementField_t [count];
e->mFieldCount = count;
for (size_t ct=0; ct < count; ct++) {
@@ -228,26 +233,11 @@ const Element * Element::create(Context *rsc, size_t count, const Element **ein,
}
e->compute();
+ ObjectBase::asyncLock();
rsc->mStateElement.mElements.push(e);
- return e;
-}
-
-String8 Element::getGLSLType(uint32_t indent) const {
- String8 s;
- for (uint32_t ct=0; ct < indent; ct++) {
- s.append(" ");
- }
+ ObjectBase::asyncUnlock();
- if (!mFieldCount) {
- // Basic component.
- s.append(mComponent.getGLSLType());
- } else {
- rsAssert(0);
- //s.append("struct ");
- //s.append(getCStructBody(indent));
- }
-
- return s;
+ return returnRef;
}
void Element::incRefs(const void *ptr) const {
@@ -294,6 +284,23 @@ void Element::decRefs(const void *ptr) const {
}
}
+void Element::Builder::add(const Element *e, const char *nameStr, uint32_t arraySize) {
+ mBuilderElementRefs.push(ObjectBaseRef<const Element>(e));
+ mBuilderElements.push(e);
+ mBuilderNameStrings.push(nameStr);
+ mBuilderNameLengths.push(strlen(nameStr));
+ mBuilderArrays.push(arraySize);
+
+}
+
+ObjectBaseRef<const Element> Element::Builder::create(Context *rsc) {
+ return Element::createRef(rsc, mBuilderElements.size(),
+ &(mBuilderElements.editArray()[0]),
+ &(mBuilderNameStrings.editArray()[0]),
+ mBuilderNameLengths.editArray(),
+ mBuilderArrays.editArray());
+}
+
ElementState::ElementState() {
const uint32_t initialCapacity = 32;
@@ -324,10 +331,10 @@ void ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint
const Element *ElementState::elementBuilderCreate(Context *rsc) {
return Element::create(rsc, mBuilderElements.size(),
- &(mBuilderElements.editArray()[0]),
- &(mBuilderNameStrings.editArray()[0]),
- mBuilderNameLengths.editArray(),
- mBuilderArrays.editArray());
+ &(mBuilderElements.editArray()[0]),
+ &(mBuilderNameStrings.editArray()[0]),
+ mBuilderNameLengths.editArray(),
+ mBuilderArrays.editArray());
}
@@ -342,9 +349,7 @@ RsElement rsi_ElementCreate(Context *rsc,
RsDataKind dk,
bool norm,
uint32_t vecSize) {
- const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
- e->incUserRef();
- return (RsElement)e;
+ return (RsElement)Element::create(rsc, dt, dk, norm, vecSize);
}
@@ -358,15 +363,15 @@ RsElement rsi_ElementCreate2(Context *rsc,
const uint32_t * arraySizes,
size_t arraySizes_length) {
- const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
- e->incUserRef();
- return (RsElement)e;
+ return (RsElement)Element::create(rsc, ein_length, (const Element **)ein,
+ names, nameLengths, arraySizes);
}
}
}
-void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData, uint32_t elemDataSize) {
+void rsaElementGetNativeData(RsContext con, RsElement elem,
+ uint32_t *elemData, uint32_t elemDataSize) {
rsAssert(elemDataSize == 5);
// we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements
Element *e = static_cast<Element *>(elem);
@@ -378,7 +383,8 @@ void rsaElementGetNativeData(RsContext con, RsElement elem, uint32_t *elemData,
(*elemData++) = e->getFieldCount();
}
-void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids, const char **names, uint32_t dataSize) {
+void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids,
+ const char **names, uint32_t dataSize) {
Element *e = static_cast<Element *>(elem);
rsAssert(e->getFieldCount() == dataSize);
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 26e2760c124b..c3ef25038d33 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -28,8 +28,17 @@ namespace renderscript {
// An element is a group of Components that occupies one cell in a structure.
class Element : public ObjectBase {
public:
- ~Element();
-
+ class Builder {
+ public:
+ void add(const Element *e, const char *nameStr, uint32_t arraySize);
+ ObjectBaseRef<const Element> create(Context *rsc);
+ private:
+ Vector<ObjectBaseRef<const Element> > mBuilderElementRefs;
+ Vector<const Element *> mBuilderElements;
+ Vector<const char*> mBuilderNameStrings;
+ Vector<size_t> mBuilderNameLengths;
+ Vector<uint32_t> mBuilderArrays;
+ };
uint32_t getGLType() const;
uint32_t getGLFormat() const;
@@ -55,24 +64,45 @@ public:
RsDataKind getKind() const {return mComponent.getKind();}
uint32_t getBits() const {return mBits;}
- String8 getGLSLType(uint32_t indent=0) const;
-
void dumpLOGV(const char *prefix) const;
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_ELEMENT; }
static Element *createFromStream(Context *rsc, IStream *stream);
- static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
- bool isNorm, uint32_t vecSize);
- static const Element * create(Context *rsc, size_t count, const Element **,
- const char **, const size_t * lengths, const uint32_t *asin);
+ static ObjectBaseRef<const Element> createRef(Context *rsc,
+ RsDataType dt,
+ RsDataKind dk,
+ bool isNorm,
+ uint32_t vecSize);
+ static ObjectBaseRef<const Element> createRef(Context *rsc, size_t count,
+ const Element **,
+ const char **,
+ const size_t * lengths,
+ const uint32_t *asin);
+
+ static const Element* create(Context *rsc,
+ RsDataType dt,
+ RsDataKind dk,
+ bool isNorm,
+ uint32_t vecSize) {
+ ObjectBaseRef<const Element> elem = createRef(rsc, dt, dk, isNorm, vecSize);
+ elem->incUserRef();
+ return elem.get();
+ }
+ static const Element* create(Context *rsc, size_t count,
+ const Element **ein,
+ const char **nin,
+ const size_t * lengths,
+ const uint32_t *asin) {
+ ObjectBaseRef<const Element> elem = createRef(rsc, count, ein, nin, lengths, asin);
+ elem->incUserRef();
+ return elem.get();
+ }
void incRefs(const void *) const;
void decRefs(const void *) const;
bool getHasReferences() const {return mHasReference;}
- bool isEqual(const Element *other) const;
-
protected:
// deallocate any components that are part of this element.
void clear();
@@ -88,12 +118,15 @@ protected:
bool mHasReference;
+ virtual ~Element();
Element(Context *);
Component mComponent;
uint32_t mBits;
void compute();
+
+ virtual void preDestroy() const;
};
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index cd02c24b981f..df5dc128061b 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -68,7 +68,7 @@ void FileA3D::parseHeader(IStream *headerStream) {
for (uint32_t i = 0; i < numIndexEntries; i ++) {
A3DIndexEntry *entry = new A3DIndexEntry();
headerStream->loadString(&entry->mObjectName);
- LOGV("Header data, entry name = %s", entry->mObjectName.string());
+ //LOGV("Header data, entry name = %s", entry->mObjectName.string());
entry->mType = (RsA3DClassID)headerStream->loadU32();
if (mUse64BitOffsets){
entry->mOffset = headerStream->loadOffset();
@@ -369,7 +369,7 @@ RsObjectBase rsaFileA3DGetEntryByIndex(RsContext con, uint32_t index, RsFile fil
}
ObjectBase *obj = fa3d->initializeFromEntry(index);
- LOGV("Returning object with name %s", obj->getName());
+ //LOGV("Returning object with name %s", obj->getName());
return obj;
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index ce674f420b11..7efed9d9f948 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -490,49 +490,47 @@ void FontState::initRenderState() {
shaderString.append(" gl_FragColor = col;\n");
shaderString.append("}\n");
- const Element *colorElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
- const Element *gammaElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
- mRSC->mStateElement.elementBuilderBegin();
- mRSC->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
- mRSC->mStateElement.elementBuilderAdd(gammaElem, "Gamma", 1);
- const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC);
+ ObjectBaseRef<const Element> colorElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ ObjectBaseRef<const Element> gammaElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
+ Element::Builder builder;
+ builder.add(colorElem.get(), "Color", 1);
+ builder.add(gammaElem.get(), "Gamma", 1);
+ ObjectBaseRef<const Element> constInput = builder.create(mRSC);
- Type *inputType = Type::getType(mRSC, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(mRSC, constInput.get(), 1, 0, 0, false, false);
uint32_t tmp[4];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
tmp[2] = RS_PROGRAM_PARAM_TEXTURE_TYPE;
tmp[3] = RS_TEXTURE_2D;
- mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType,
+ mFontShaderFConstant.set(Allocation::createAllocation(mRSC, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS));
ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(),
shaderString.length(), tmp, 4);
mFontShaderF.set(pf);
mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0);
- Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
- RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP);
- mFontSampler.set(sampler);
- mFontShaderF->bindSampler(mRSC, 0, sampler);
-
- ProgramStore *fontStore = new ProgramStore(mRSC, true, true, true, true,
- false, false,
- RS_BLEND_SRC_SRC_ALPHA,
- RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
- RS_DEPTH_FUNC_ALWAYS);
- mFontProgramStore.set(fontStore);
+ mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
+ RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP).get());
+ mFontShaderF->bindSampler(mRSC, 0, mFontSampler.get());
+
+ mFontProgramStore.set(ProgramStore::getProgramStore(mRSC, true, true, true, true,
+ false, false,
+ RS_BLEND_SRC_SRC_ALPHA,
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,
+ RS_DEPTH_FUNC_ALWAYS).get());
mFontProgramStore->init();
}
void FontState::initTextTexture() {
- const Element *alphaElem = Element::create(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
+ ObjectBaseRef<const Element> alphaElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_8, RS_KIND_PIXEL_A, true, 1);
// We will allocate a texture to initially hold 32 character bitmaps
- Type *texType = Type::getType(mRSC, alphaElem, 1024, 256, 0, false, false);
+ ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), 1024, 256, 0, false, false);
- Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType,
+ Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE);
mTextTexture.set(cacheAlloc);
mTextTexture->syncAll(mRSC, RS_ALLOCATION_USAGE_SCRIPT);
@@ -557,11 +555,11 @@ void FontState::initTextTexture() {
// Avoid having to reallocate memory and render quad by quad
void FontState::initVertexArrayBuffers() {
// Now lets write index data
- const Element *indexElem = Element::create(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
+ ObjectBaseRef<const Element> indexElem = Element::createRef(mRSC, RS_TYPE_UNSIGNED_16, RS_KIND_USER, false, 1);
uint32_t numIndicies = mMaxNumberOfQuads * 6;
- Type *indexType = Type::getType(mRSC, indexElem, numIndicies, 0, 0, false, false);
+ ObjectBaseRef<Type> indexType = Type::getTypeRef(mRSC, indexElem.get(), numIndicies, 0, 0, false, false);
- Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType,
+ Allocation *indexAlloc = Allocation::createAllocation(mRSC, indexType.get(),
RS_ALLOCATION_USAGE_SCRIPT |
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX);
uint16_t *indexPtr = (uint16_t*)indexAlloc->getPtr();
@@ -582,19 +580,19 @@ void FontState::initVertexArrayBuffers() {
indexAlloc->sendDirty(mRSC);
- const Element *posElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
- const Element *texElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
+ ObjectBaseRef<const Element> posElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
+ ObjectBaseRef<const Element> texElem = Element::createRef(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
- mRSC->mStateElement.elementBuilderBegin();
- mRSC->mStateElement.elementBuilderAdd(posElem, "position", 1);
- mRSC->mStateElement.elementBuilderAdd(texElem, "texture0", 1);
- const Element *vertexDataElem = mRSC->mStateElement.elementBuilderCreate(mRSC);
+ Element::Builder builder;
+ builder.add(posElem.get(), "position", 1);
+ builder.add(texElem.get(), "texture0", 1);
+ ObjectBaseRef<const Element> vertexDataElem = builder.create(mRSC);
- Type *vertexDataType = Type::getType(mRSC, vertexDataElem,
- mMaxNumberOfQuads * 4,
- 0, 0, false, false);
+ ObjectBaseRef<Type> vertexDataType = Type::getTypeRef(mRSC, vertexDataElem.get(),
+ mMaxNumberOfQuads * 4,
+ 0, 0, false, false);
- Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType,
+ Allocation *vertexAlloc = Allocation::createAllocation(mRSC, vertexDataType.get(),
RS_ALLOCATION_USAGE_SCRIPT);
mTextMeshPtr = (float*)vertexAlloc->getPtr();
@@ -735,7 +733,7 @@ void FontState::renderText(const char *text, uint32_t len, int32_t x, int32_t y,
Font *currentFont = mRSC->getFont();
if (!currentFont) {
if (!mDefault.get()) {
- String8 fontsDir("/fonts/DroidSans.ttf");
+ String8 fontsDir("/fonts/Roboto-Regular.ttf");
String8 fullPath(getenv("ANDROID_ROOT"));
fullPath += fontsDir;
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index b0e1430e228b..679591ca434f 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -146,7 +146,6 @@ public:
void deinit(Context *rsc);
ObjectBaseRef<Font> mDefault;
- ObjectBaseRef<Font> mLast;
void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
uint32_t startIndex = 0, int numGlyphs = -1,
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index 7023a1ff2863..02a76ab027d2 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -129,21 +129,23 @@ void LocklessCommandFifo::flush() {
//dumpState("flush 2");
}
-void LocklessCommandFifo::wait() {
+bool LocklessCommandFifo::wait(uint64_t timeout) {
while (isEmpty() && !mInShutdown) {
mSignalToControl.set();
- mSignalToWorker.wait();
+ return mSignalToWorker.wait(timeout);
}
+ return true;
}
-const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) {
+const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData, uint64_t timeout) {
while (1) {
//dumpState("get");
- wait();
- if (mInShutdown) {
+ wait(timeout);
+
+ if (isEmpty() || mInShutdown) {
*command = 0;
*bytesData = 0;
- return 0;
+ return NULL;
}
*command = reinterpret_cast<const uint16_t *>(mGet)[0];
diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h
index eabdc3e97f05..4962ef614cc0 100644
--- a/libs/rs/rsLocklessFifo.h
+++ b/libs/rs/rsLocklessFifo.h
@@ -57,9 +57,9 @@ public:
void commitSync(uint32_t command, uint32_t bytes);
void flush();
- void wait();
+ bool wait(uint64_t timeout = 0);
- const void * get(uint32_t *command, uint32_t *bytesData);
+ const void * get(uint32_t *command, uint32_t *bytesData, uint64_t timeout = 0);
void next();
void makeSpace(uint32_t bytes);
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index 01850f1e2511..c7cfb0e2e8b0 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -114,7 +114,10 @@ public:
}
ObjectBaseRef & operator= (const ObjectBaseRef &ref) {
- return ObjectBaseRef(ref);
+ if (&ref != this) {
+ set(ref);
+ }
+ return *this;
}
~ObjectBaseRef() {
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index b1d8f48b9ee3..33eb422e3354 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -116,7 +116,7 @@ void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) {
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
return;
}
- if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) {
+ if (alloc->getType() != mHal.state.constantTypes[slot].get()) {
LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch",
slot, (uint32_t)this);
rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation");
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 356ff778f126..ff2952051162 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -97,18 +97,18 @@ void ProgramFragmentState::init(Context *rsc) {
shaderString.append(" gl_FragColor = col;\n");
shaderString.append("}\n");
- const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
- const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
+ ObjectBaseRef<const Element> colorElem = Element::createRef(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ Element::Builder builder;
+ builder.add(colorElem.get(), "Color", 1);
+ ObjectBaseRef<const Element> constInput = builder.create(rsc);
- Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
uint32_t tmp[2];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
- Allocation *constAlloc = Allocation::createAllocation(rsc, inputType,
+ Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
shaderString.length(), tmp, 2);
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index 435561d7308a..945b5eca68fd 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -37,6 +37,15 @@ ProgramRaster::ProgramRaster(Context *rsc, bool pointSmooth,
rsc->mHal.funcs.raster.init(rsc, this);
}
+void ProgramRaster::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateRaster.mRasterPrograms.size(); ct++) {
+ if (mRSC->mStateRaster.mRasterPrograms[ct] == this) {
+ mRSC->mStateRaster.mRasterPrograms.removeAt(ct);
+ break;
+ }
+ }
+}
+
ProgramRaster::~ProgramRaster() {
mRSC->mHal.funcs.raster.destroy(mRSC, this);
}
@@ -65,8 +74,8 @@ ProgramRasterState::~ProgramRasterState() {
}
void ProgramRasterState::init(Context *rsc) {
- ProgramRaster *pr = new ProgramRaster(rsc, false, false, false, 1.f, RS_CULL_BACK);
- mDefault.set(pr);
+ mDefault.set(ProgramRaster::getProgramRaster(rsc, false, false,
+ false, 1.f, RS_CULL_BACK).get());
}
void ProgramRasterState::deinit(Context *rsc) {
@@ -74,19 +83,47 @@ void ProgramRasterState::deinit(Context *rsc) {
mLast.clear();
}
-namespace android {
-namespace renderscript {
+ObjectBaseRef<ProgramRaster> ProgramRaster::getProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull) {
+ ObjectBaseRef<ProgramRaster> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateRaster.mRasterPrograms.size(); ct++) {
+ ProgramRaster *existing = rsc->mStateRaster.mRasterPrograms[ct];
+ if (existing->mHal.state.pointSmooth != pointSmooth) continue;
+ if (existing->mHal.state.lineSmooth != lineSmooth) continue;
+ if (existing->mHal.state.pointSprite != pointSprite) continue;
+ if (existing->mHal.state.lineWidth != lineWidth) continue;
+ if (existing->mHal.state.cull != cull) continue;
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
-RsProgramRaster rsi_ProgramRasterCreate(Context * rsc,
- bool pointSmooth,
- bool lineSmooth,
- bool pointSprite,
- float lineWidth,
- RsCullMode cull) {
ProgramRaster *pr = new ProgramRaster(rsc, pointSmooth,
lineSmooth, pointSprite, lineWidth, cull);
+ returnRef.set(pr);
+
+ ObjectBase::asyncLock();
+ rsc->mStateRaster.mRasterPrograms.push(pr);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
+namespace android {
+namespace renderscript {
+
+RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, bool pointSmooth, bool lineSmooth,
+ bool pointSprite, float lineWidth, RsCullMode cull) {
+ ObjectBaseRef<ProgramRaster> pr = ProgramRaster::getProgramRaster(rsc, pointSmooth, lineSmooth,
+ pointSprite, lineWidth, cull);
pr->incUserRef();
- return pr;
+ return pr.get();
}
}
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index efdb94874197..09d7d5432c9a 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -27,19 +27,17 @@ class ProgramRasterState;
class ProgramRaster : public ProgramBase {
public:
- ProgramRaster(Context *rsc,
- bool pointSmooth,
- bool lineSmooth,
- bool pointSprite,
- float lineWidth,
- RsCullMode cull);
- virtual ~ProgramRaster();
-
virtual void setup(const Context *, ProgramRasterState *);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_RASTER; }
static ProgramRaster *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramRaster> getProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull);
struct Hal {
mutable void *drv;
@@ -55,6 +53,17 @@ public:
Hal mHal;
protected:
+ virtual void preDestroy() const;
+ virtual ~ProgramRaster();
+
+private:
+ ProgramRaster(Context *rsc,
+ bool pointSmooth,
+ bool lineSmooth,
+ bool pointSprite,
+ float lineWidth,
+ RsCullMode cull);
+
};
class ProgramRasterState {
@@ -66,6 +75,9 @@ public:
ObjectBaseRef<ProgramRaster> mDefault;
ObjectBaseRef<ProgramRaster> mLast;
+
+ // Cache of all existing raster programs.
+ Vector<ProgramRaster *> mRasterPrograms;
};
diff --git a/libs/rs/rsProgramStore.cpp b/libs/rs/rsProgramStore.cpp
index 8fe890becb72..7e25a226d8ae 100644
--- a/libs/rs/rsProgramStore.cpp
+++ b/libs/rs/rsProgramStore.cpp
@@ -41,6 +41,15 @@ ProgramStore::ProgramStore(Context *rsc,
mHal.state.depthFunc = depthFunc;
}
+void ProgramStore::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateFragmentStore.mStorePrograms.size(); ct++) {
+ if (mRSC->mStateFragmentStore.mStorePrograms[ct] == this) {
+ mRSC->mStateFragmentStore.mStorePrograms.removeAt(ct);
+ break;
+ }
+ }
+}
+
ProgramStore::~ProgramStore() {
mRSC->mHal.funcs.store.destroy(mRSC, this);
}
@@ -71,14 +80,58 @@ ProgramStoreState::ProgramStoreState() {
ProgramStoreState::~ProgramStoreState() {
}
+ObjectBaseRef<ProgramStore> ProgramStore::getProgramStore(Context *rsc,
+ bool colorMaskR,
+ bool colorMaskG,
+ bool colorMaskB,
+ bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc,
+ RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc) {
+ ObjectBaseRef<ProgramStore> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateFragmentStore.mStorePrograms.size(); ct++) {
+ ProgramStore *existing = rsc->mStateFragmentStore.mStorePrograms[ct];
+ if (existing->mHal.state.ditherEnable != ditherEnable) continue;
+ if (existing->mHal.state.colorRWriteEnable != colorMaskR) continue;
+ if (existing->mHal.state.colorGWriteEnable != colorMaskG) continue;
+ if (existing->mHal.state.colorBWriteEnable != colorMaskB) continue;
+ if (existing->mHal.state.colorAWriteEnable != colorMaskA) continue;
+ if (existing->mHal.state.blendSrc != srcFunc) continue;
+ if (existing->mHal.state.blendDst != destFunc) continue;
+ if (existing->mHal.state.depthWriteEnable != depthMask) continue;
+ if (existing->mHal.state.depthFunc != depthFunc) continue;
+
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ ProgramStore *pfs = new ProgramStore(rsc,
+ colorMaskR, colorMaskG, colorMaskB, colorMaskA,
+ depthMask, ditherEnable,
+ srcFunc, destFunc, depthFunc);
+ returnRef.set(pfs);
+
+ pfs->init();
+
+ ObjectBase::asyncLock();
+ rsc->mStateFragmentStore.mStorePrograms.push(pfs);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
+
+
void ProgramStoreState::init(Context *rsc) {
- ProgramStore *ps = new ProgramStore(rsc,
- true, true, true, true,
- true, true,
- RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
- RS_DEPTH_FUNC_LESS);
- ps->init();
- mDefault.set(ps);
+ mDefault.set(ProgramStore::getProgramStore(rsc,
+ true, true, true, true,
+ true, true,
+ RS_BLEND_SRC_ONE, RS_BLEND_DST_ZERO,
+ RS_DEPTH_FUNC_LESS).get());
}
void ProgramStoreState::deinit(Context *rsc) {
@@ -96,13 +149,14 @@ RsProgramStore rsi_ProgramStoreCreate(Context *rsc,
RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
RsDepthFunc depthFunc) {
- ProgramStore *pfs = new ProgramStore(rsc,
- colorMaskR, colorMaskG, colorMaskB, colorMaskA,
- depthMask, ditherEnable,
- srcFunc, destFunc, depthFunc);
- pfs->init();
- pfs->incUserRef();
- return pfs;
+
+ ObjectBaseRef<ProgramStore> ps = ProgramStore::getProgramStore(rsc,
+ colorMaskR, colorMaskG,
+ colorMaskB, colorMaskA,
+ depthMask, ditherEnable,
+ srcFunc, destFunc, depthFunc);
+ ps->incUserRef();
+ return ps.get();
}
}
diff --git a/libs/rs/rsProgramStore.h b/libs/rs/rsProgramStore.h
index 77b3881fc8ee..e21f039678b3 100644
--- a/libs/rs/rsProgramStore.h
+++ b/libs/rs/rsProgramStore.h
@@ -28,18 +28,17 @@ class ProgramStoreState;
class ProgramStore : public ProgramBase {
public:
- ProgramStore(Context *,
- bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
- bool depthMask, bool ditherEnable,
- RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
- RsDepthFunc depthFunc);
- virtual ~ProgramStore();
-
virtual void setup(const Context *, ProgramStoreState *);
virtual void serialize(OStream *stream) const;
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_STORE; }
static ProgramStore *createFromStream(Context *rsc, IStream *stream);
+ static ObjectBaseRef<ProgramStore> getProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG,
+ bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
void init();
@@ -66,6 +65,15 @@ public:
Hal mHal;
protected:
+ virtual void preDestroy() const;
+ virtual ~ProgramStore();
+
+private:
+ ProgramStore(Context *,
+ bool colorMaskR, bool colorMaskG, bool colorMaskB, bool colorMaskA,
+ bool depthMask, bool ditherEnable,
+ RsBlendSrcFunc srcFunc, RsBlendDstFunc destFunc,
+ RsDepthFunc depthFunc);
};
class ProgramStoreState {
@@ -77,6 +85,9 @@ public:
ObjectBaseRef<ProgramStore> mDefault;
ObjectBaseRef<ProgramStore> mLast;
+
+ // Cache of all existing store programs.
+ Vector<ProgramStore *> mStorePrograms;
};
}
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 058a4564e03f..51cb2a8ad490 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -150,26 +150,30 @@ ProgramVertexState::~ProgramVertexState() {
}
void ProgramVertexState::init(Context *rsc) {
- const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1);
- const Element *f2Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 2);
- const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3);
- const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
-
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1);
- rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1);
- const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
-
- rsc->mStateElement.elementBuilderBegin();
- rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1);
- rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1);
- rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1);
- rsc->mStateElement.elementBuilderAdd(f2Elem, "texture0", 1);
- const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc);
-
- Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+ ObjectBaseRef<const Element> matrixElem = Element::createRef(rsc, RS_TYPE_MATRIX_4X4,
+ RS_KIND_USER, false, 1);
+ ObjectBaseRef<const Element> f2Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 2);
+ ObjectBaseRef<const Element> f3Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 3);
+ ObjectBaseRef<const Element> f4Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
+ RS_KIND_USER, false, 4);
+
+ Element::Builder constBuilder;
+ constBuilder.add(matrixElem.get(), "MV", 1);
+ constBuilder.add(matrixElem.get(), "P", 1);
+ constBuilder.add(matrixElem.get(), "TexMatrix", 1);
+ constBuilder.add(matrixElem.get(), "MVP", 1);
+ ObjectBaseRef<const Element> constInput = constBuilder.create(rsc);
+
+ Element::Builder inputBuilder;
+ inputBuilder.add(f4Elem.get(), "position", 1);
+ inputBuilder.add(f4Elem.get(), "color", 1);
+ inputBuilder.add(f3Elem.get(), "normal", 1);
+ inputBuilder.add(f2Elem.get(), "texture0", 1);
+ ObjectBaseRef<const Element> attrElem = inputBuilder.create(rsc);
+
+ ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
String8 shaderString(RS_SHADER_INTERNAL);
shaderString.append("varying vec4 varColor;\n");
@@ -183,13 +187,13 @@ void ProgramVertexState::init(Context *rsc) {
uint32_t tmp[4];
tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
- tmp[1] = (uint32_t)inputType;
+ tmp[1] = (uint32_t)inputType.get();
tmp[2] = RS_PROGRAM_PARAM_INPUT;
- tmp[3] = (uint32_t)attrElem;
+ tmp[3] = (uint32_t)attrElem.get();
ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(),
shaderString.length(), tmp, 4);
- Allocation *alloc = Allocation::createAllocation(rsc, inputType,
+ Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(),
RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
pv->bindAllocation(rsc, alloc, 0);
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 2a05d16e9bbe..5fc64a42cd1f 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -48,6 +48,15 @@ Sampler::~Sampler() {
mRSC->mHal.funcs.sampler.destroy(mRSC, this);
}
+void Sampler::preDestroy() const {
+ for (uint32_t ct = 0; ct < mRSC->mStateSampler.mAllSamplers.size(); ct++) {
+ if (mRSC->mStateSampler.mAllSamplers[ct] == this) {
+ mRSC->mStateSampler.mAllSamplers.removeAt(ct);
+ break;
+ }
+ }
+}
+
void Sampler::bindToContext(SamplerState *ss, uint32_t slot) {
ss->mSamplers[slot].set(this);
mBoundSlot = slot;
@@ -66,6 +75,39 @@ Sampler *Sampler::createFromStream(Context *rsc, IStream *stream) {
return NULL;
}
+ObjectBaseRef<Sampler> Sampler::getSampler(Context *rsc,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso) {
+ ObjectBaseRef<Sampler> returnRef;
+ ObjectBase::asyncLock();
+ for (uint32_t ct = 0; ct < rsc->mStateSampler.mAllSamplers.size(); ct++) {
+ Sampler *existing = rsc->mStateSampler.mAllSamplers[ct];
+ if (existing->mHal.state.magFilter != magFilter) continue;
+ if (existing->mHal.state.minFilter != minFilter ) continue;
+ if (existing->mHal.state.wrapS != wrapS) continue;
+ if (existing->mHal.state.wrapT != wrapT) continue;
+ if (existing->mHal.state.wrapR != wrapR) continue;
+ if (existing->mHal.state.aniso != aniso) continue;
+ returnRef.set(existing);
+ ObjectBase::asyncUnlock();
+ return returnRef;
+ }
+ ObjectBase::asyncUnlock();
+
+ Sampler *s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ returnRef.set(s);
+
+ ObjectBase::asyncLock();
+ rsc->mStateSampler.mAllSamplers.push(s);
+ ObjectBase::asyncUnlock();
+
+ return returnRef;
+}
+
////////////////////////////////
namespace android {
@@ -78,9 +120,10 @@ RsSampler rsi_SamplerCreate(Context * rsc,
RsSamplerValue wrapT,
RsSamplerValue wrapR,
float aniso) {
- Sampler * s = new Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+ ObjectBaseRef<Sampler> s = Sampler::getSampler(rsc, magFilter, minFilter,
+ wrapS, wrapT, wrapR, aniso);
s->incUserRef();
- return s;
+ return s.get();
}
}}
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 90b6082c139d..e698132d0f70 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -30,16 +30,13 @@ class SamplerState;
class Sampler : public ObjectBase {
public:
- Sampler(Context *,
- RsSamplerValue magFilter,
- RsSamplerValue minFilter,
- RsSamplerValue wrapS,
- RsSamplerValue wrapT,
- RsSamplerValue wrapR,
- float aniso = 1.0f);
-
- virtual ~Sampler();
-
+ static ObjectBaseRef<Sampler> getSampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
void bindToContext(SamplerState *, uint32_t slot);
void unbindFromContext(SamplerState *);
@@ -65,14 +62,33 @@ public:
protected:
int32_t mBoundSlot;
+ virtual void preDestroy() const;
+ virtual ~Sampler();
+
private:
Sampler(Context *);
+ Sampler(Context *,
+ RsSamplerValue magFilter,
+ RsSamplerValue minFilter,
+ RsSamplerValue wrapS,
+ RsSamplerValue wrapT,
+ RsSamplerValue wrapR,
+ float aniso = 1.0f);
};
class SamplerState {
public:
ObjectBaseRef<Sampler> mSamplers[RS_MAX_SAMPLER_SLOT];
+ void init(Context *rsc) {
+ }
+ void deinit(Context *rsc) {
+ for (uint32_t i = 0; i < RS_MAX_SAMPLER_SLOT; i ++) {
+ mSamplers[i].clear();
+ }
+ }
+ // Cache of all existing raster programs.
+ Vector<Sampler *> mAllSamplers;
};
}
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index e8b1014f53dd..dccf71f046c8 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -19,6 +19,10 @@
#include "utils/Timers.h"
#include "utils/StopWatch.h"
+#ifndef ANDROID_RS_SERIALIZE
+#include <bcinfo/BitcodeTranslator.h>
+#endif
+
using namespace android;
using namespace android::renderscript;
@@ -28,9 +32,18 @@ using namespace android::renderscript;
ScriptC * sc = (ScriptC *) tls->mScript
ScriptC::ScriptC(Context *rsc) : Script(rsc) {
+#ifndef ANDROID_RS_SERIALIZE
+ BT = NULL;
+#endif
}
ScriptC::~ScriptC() {
+#ifndef ANDROID_RS_SERIALIZE
+ if (BT) {
+ delete BT;
+ BT = NULL;
+ }
+#endif
mRSC->mHal.funcs.script.destroy(mRSC, this);
}
@@ -181,6 +194,22 @@ bool ScriptC::runCompiler(Context *rsc,
size_t bitcodeLen) {
//LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
+#ifndef ANDROID_RS_SERIALIZE
+ uint32_t sdkVersion = rsc->getTargetSdkVersion();
+ if (BT) {
+ delete BT;
+ }
+ BT = new bcinfo::BitcodeTranslator((const char *)bitcode, bitcodeLen,
+ sdkVersion);
+ if (!BT->translate()) {
+ LOGE("Failed to translate bitcode from version: %u", sdkVersion);
+ delete BT;
+ BT = NULL;
+ return false;
+ }
+ bitcode = (const uint8_t *) BT->getTranslatedBitcode();
+ bitcodeLen = BT->getTranslatedBitcodeSize();
+#endif
rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0);
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 5c191d93cf46..c65a5bf7a06b 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -21,6 +21,9 @@
#include "RenderScriptEnv.h"
+#ifndef ANDROID_RS_SERIALIZE
+#include "bcinfo/BitcodeTranslator.h"
+#endif
// ---------------------------------------------------------------------------
namespace android {
@@ -61,6 +64,10 @@ public:
void setupScript(Context *);
void setupGLState(Context *);
Script * setTLS(Script *);
+ private:
+#ifndef ANDROID_RS_SERIALIZE
+ bcinfo::BitcodeTranslator *BT;
+#endif
};
class ScriptCState {
diff --git a/libs/rs/rsSignal.cpp b/libs/rs/rsSignal.cpp
index ccd20b95c100..413ac2bb201e 100644
--- a/libs/rs/rsSignal.cpp
+++ b/libs/rs/rsSignal.cpp
@@ -68,26 +68,43 @@ void Signal::set() {
}
}
-void Signal::wait() {
+bool Signal::wait(uint64_t timeout) {
int status;
+ bool ret = false;
status = pthread_mutex_lock(&mMutex);
if (status) {
LOGE("LocklessCommandFifo: error %i locking for condition.", status);
- return;
+ return false;
}
if (!mSet) {
- status = pthread_cond_wait(&mCondition, &mMutex);
- if (status) {
- LOGE("LocklessCommandFifo: error %i waiting on condition.", status);
+ if (!timeout) {
+ status = pthread_cond_wait(&mCondition, &mMutex);
+ } else {
+#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
+ status = pthread_cond_timeout_np(&mCondition, &mMutex, timeout / 1000000);
+#else
+ // This is safe it will just make things less reponsive
+ status = pthread_cond_wait(&mCondition, &mMutex);
+#endif
+ }
+ }
+
+ if (!status) {
+ mSet = false;
+ ret = true;
+ } else {
+ if (status != ETIMEDOUT) {
+ LOGE("LocklessCommandFifo: error %i waiting for condition.", status);
}
}
- mSet = false;
status = pthread_mutex_unlock(&mMutex);
if (status) {
LOGE("LocklessCommandFifo: error %i unlocking for condition.", status);
}
+
+ return ret;
}
diff --git a/libs/rs/rsSignal.h b/libs/rs/rsSignal.h
index 2e760f158e53..fc3188301334 100644
--- a/libs/rs/rsSignal.h
+++ b/libs/rs/rsSignal.h
@@ -31,7 +31,10 @@ public:
bool init();
void set();
- void wait();
+
+ // returns true if the signal occured
+ // false for timeout
+ bool wait(uint64_t timeout = 0);
protected:
bool mSet;
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 1c8b89c25d55..fe2c52ea4662 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -113,8 +113,10 @@ void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
}
-bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) {
+bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait) {
bool ret = false;
+ uint64_t startTime = con->getTime();
+
while (!mToCore.isEmpty() || waitForCommand) {
uint32_t cmdID = 0;
uint32_t cmdSize = 0;
@@ -122,9 +124,17 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) {
if (con->props.mLogTimes) {
con->timerSet(Context::RS_TIMER_IDLE);
}
- const void * data = mToCore.get(&cmdID, &cmdSize);
+
+ uint64_t delay = 0;
+ if (waitForCommand) {
+ delay = timeToWait - (con->getTime() - startTime);
+ if (delay > timeToWait) {
+ delay = 0;
+ }
+ }
+ const void * data = mToCore.get(&cmdID, &cmdSize, delay);
if (!cmdSize) {
- // exception occured, probably shutdown.
+ // exception or timeout occurred.
return false;
}
if (con->props.mLogTimes) {
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index cad731864942..9036118a0fa0 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -37,7 +37,7 @@ public:
// Plays back commands from the client.
// Returns true if any commands were processed.
- bool playCoreCommands(Context *con, bool waitForCommand);
+ bool playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait);
//LocklessCommandFifo mToCore;
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 10e3182c6389..9a6a31b4f89f 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -25,7 +25,7 @@ Type::Type(Context *rsc) : ObjectBase(rsc) {
clear();
}
-void Type::preDestroy() {
+void Type::preDestroy() const {
for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
if (mRSC->mStateType.mTypes[ct] == this) {
mRSC->mStateType.mTypes.removeAt(ct);
@@ -58,6 +58,7 @@ TypeState::TypeState() {
}
TypeState::~TypeState() {
+ rsAssert(!mTypes.size());
}
size_t Type::getOffsetForFace(uint32_t face) const {
@@ -183,7 +184,9 @@ Type *Type::createFromStream(Context *rsc, IStream *stream) {
uint32_t z = stream->loadU32();
uint8_t lod = stream->loadU8();
uint8_t faces = stream->loadU8();
- return Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
+ Type *type = Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0 );
+ elem->decUserRef();
+ return type;
}
bool Type::getIsNp2() const {
@@ -203,24 +206,11 @@ bool Type::getIsNp2() const {
return false;
}
-bool Type::isEqual(const Type *other) const {
- if (other == NULL) {
- return false;
- }
- if (other->getElement()->isEqual(getElement()) &&
- other->getDimX() == mDimX &&
- other->getDimY() == mDimY &&
- other->getDimZ() == mDimZ &&
- other->getDimLOD() == mDimLOD &&
- other->getDimFaces() == mFaces) {
- return true;
- }
- return false;
-}
+ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces) {
+ ObjectBaseRef<Type> returnRef;
-Type * Type::getType(Context *rsc, const Element *e,
- uint32_t dimX, uint32_t dimY, uint32_t dimZ,
- bool dimLOD, bool dimFaces) {
TypeState * stc = &rsc->mStateType;
ObjectBase::asyncLock();
@@ -232,14 +222,15 @@ Type * Type::getType(Context *rsc, const Element *e,
if (t->getDimZ() != dimZ) continue;
if (t->getDimLOD() != dimLOD) continue;
if (t->getDimFaces() != dimFaces) continue;
- t->incUserRef();
+ returnRef.set(t);
ObjectBase::asyncUnlock();
- return t;
+ return returnRef;
}
ObjectBase::asyncUnlock();
Type *nt = new Type(rsc);
+ returnRef.set(nt);
nt->mElement.set(e);
nt->mDimX = dimX;
nt->mDimY = dimY;
@@ -247,25 +238,24 @@ Type * Type::getType(Context *rsc, const Element *e,
nt->mDimLOD = dimLOD;
nt->mFaces = dimFaces;
nt->compute();
- nt->incUserRef();
ObjectBase::asyncLock();
stc->mTypes.push(nt);
ObjectBase::asyncUnlock();
- return nt;
+ return returnRef;
}
-Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
- return getType(rsc, mElement.get(), dimX,
- mDimY, mDimZ, mDimLOD, mFaces);
+ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
+ return getTypeRef(rsc, mElement.get(), dimX,
+ mDimY, mDimZ, mDimLOD, mFaces);
}
-Type * Type::cloneAndResize2D(Context *rsc,
+ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
uint32_t dimX,
uint32_t dimY) const {
- return getType(rsc, mElement.get(), dimX, dimY,
- mDimZ, mDimLOD, mFaces);
+ return getTypeRef(rsc, mElement.get(), dimX, dimY,
+ mDimZ, mDimLOD, mFaces);
}
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 086db337093b..bc0d9ffdbe46 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -62,14 +62,20 @@ public:
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_TYPE; }
static Type *createFromStream(Context *rsc, IStream *stream);
- bool isEqual(const Type *other) const;
+ ObjectBaseRef<Type> cloneAndResize1D(Context *rsc, uint32_t dimX) const;
+ ObjectBaseRef<Type> cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
- Type * cloneAndResize1D(Context *rsc, uint32_t dimX) const;
- Type * cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
+ static ObjectBaseRef<Type> getTypeRef(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces);
- static Type * getType(Context *rsc, const Element *e,
- uint32_t dimX, uint32_t dimY, uint32_t dimZ,
- bool dimLOD, bool dimFaces);
+ static Type* getType(Context *rsc, const Element *e,
+ uint32_t dimX, uint32_t dimY, uint32_t dimZ,
+ bool dimLOD, bool dimFaces) {
+ ObjectBaseRef<Type> type = getTypeRef(rsc, e, dimX, dimY, dimZ, dimLOD, dimFaces);
+ type->incUserRef();
+ return type.get();
+ }
protected:
struct LOD {
@@ -105,7 +111,7 @@ protected:
uint32_t mLODCount;
protected:
- virtual void preDestroy();
+ virtual void preDestroy() const;
virtual ~Type();
private:
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index 6a4537b392a2..21dff218c868 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -40,6 +40,19 @@ class FBOCache;
typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
+typedef struct {
+ const void *in;
+ void *out;
+ const void *usr;
+ size_t usr_len;
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+ uint32_t lod;
+ RsAllocationCubemapFace face;
+ uint32_t ar[16];
+} RsForEachStubParamStruct;
+
/**
* Script management functions
*/
diff --git a/libs/rs/scriptc/rs_allocation.rsh b/libs/rs/scriptc/rs_allocation.rsh
new file mode 100644
index 000000000000..1e755cd38ceb
--- /dev/null
+++ b/libs/rs/scriptc/rs_allocation.rsh
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+/** @file rs_allocation.rsh
+ * \brief Allocation routines
+ *
+ *
+ */
+
+#ifndef __RS_ALLOCATION_RSH__
+#define __RS_ALLOCATION_RSH__
+
+/**
+ * Returns the Allocation for a given pointer. The pointer should point within
+ * a valid allocation. The results are undefined if the pointer is not from a
+ * valid allocation.
+ */
+extern rs_allocation __attribute__((overloadable))
+ rsGetAllocation(const void *);
+
+/**
+ * Query the dimension of an allocation.
+ *
+ * @return uint32_t The X dimension of the allocation.
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAllocationGetDimX(rs_allocation);
+
+/**
+ * Query the dimension of an allocation.
+ *
+ * @return uint32_t The Y dimension of the allocation.
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAllocationGetDimY(rs_allocation);
+
+/**
+ * Query the dimension of an allocation.
+ *
+ * @return uint32_t The Z dimension of the allocation.
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAllocationGetDimZ(rs_allocation);
+
+/**
+ * Query an allocation for the presence of more than one LOD.
+ *
+ * @return uint32_t Returns 1 if more than one LOD is present, 0 otherwise.
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAllocationGetDimLOD(rs_allocation);
+
+/**
+ * Query an allocation for the presence of more than one face.
+ *
+ * @return uint32_t Returns 1 if more than one face is present, 0 otherwise.
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAllocationGetDimFaces(rs_allocation);
+
+/**
+ * Copy part of an allocation from another allocation.
+ *
+ * @param dstAlloc Allocation to copy data into.
+ * @param dstOff The offset of the first element to be copied in
+ * the destination allocation.
+ * @param dstMip Mip level in the destination allocation.
+ * @param count The number of elements to be copied.
+ * @param srcAlloc The source data allocation.
+ * @param srcOff The offset of the first element in data to be
+ * copied in the source allocation.
+ * @param srcMip Mip level in the source allocation.
+ */
+extern void __attribute__((overloadable))
+ rsAllocationCopy1DRange(rs_allocation dstAlloc,
+ uint32_t dstOff, uint32_t dstMip,
+ uint32_t count,
+ rs_allocation srcAlloc,
+ uint32_t srcOff, uint32_t srcMip);
+
+/**
+ * Copy a rectangular region into the allocation from another
+ * allocation.
+ *
+ * @param dstAlloc allocation to copy data into.
+ * @param dstXoff X offset of the region to update in the
+ * destination allocation.
+ * @param dstYoff Y offset of the region to update in the
+ * destination allocation.
+ * @param dstMip Mip level in the destination allocation.
+ * @param dstFace Cubemap face of the destination allocation,
+ * ignored for allocations that aren't cubemaps.
+ * @param width Width of the incoming region to update.
+ * @param height Height of the incoming region to update.
+ * @param srcAlloc The source data allocation.
+ * @param srcXoff X offset in data of the source allocation.
+ * @param srcYoff Y offset in data of the source allocation.
+ * @param srcMip Mip level in the source allocation.
+ * @param srcFace Cubemap face of the source allocation,
+ * ignored for allocations that aren't cubemaps.
+ */
+extern void __attribute__((overloadable))
+ rsAllocationCopy2DRange(rs_allocation dstAlloc,
+ uint32_t dstXoff, uint32_t dstYoff,
+ uint32_t dstMip,
+ rs_allocation_cubemap_face dstFace,
+ uint32_t width, uint32_t height,
+ rs_allocation srcAlloc,
+ uint32_t srcXoff, uint32_t srcYoff,
+ uint32_t srcMip,
+ rs_allocation_cubemap_face srcFace);
+
+
+/**
+ * Extract a single element from an allocation.
+ */
+extern const void * __attribute__((overloadable))
+ rsGetElementAt(rs_allocation, uint32_t x);
+/**
+ * \overload
+ */
+extern const void * __attribute__((overloadable))
+ rsGetElementAt(rs_allocation, uint32_t x, uint32_t y);
+/**
+ * \overload
+ */
+extern const void * __attribute__((overloadable))
+ rsGetElementAt(rs_allocation, uint32_t x, uint32_t y, uint32_t z);
+
+#endif
+
diff --git a/libs/rs/scriptc/rs_atomic.rsh b/libs/rs/scriptc/rs_atomic.rsh
new file mode 100644
index 000000000000..95513ad623f1
--- /dev/null
+++ b/libs/rs/scriptc/rs_atomic.rsh
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+/** @file rs_atomic.rsh
+ * \brief Atomic routines
+ *
+ *
+ */
+
+#ifndef __RS_ATOMIC_RSH__
+#define __RS_ATOMIC_RSH__
+
+
+/**
+ * Atomic add one to the value at addr.
+ * Equal to rsAtomicAdd(addr, 1)
+ *
+ * @param addr Address of value to increment
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicInc(volatile int32_t* addr);
+/**
+ * Atomic add one to the value at addr.
+ * Equal to rsAtomicAdd(addr, 1)
+ *
+ * @param addr Address of value to increment
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicInc(volatile uint32_t* addr);
+
+/**
+ * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
+ *
+ * @param addr Address of value to decrement
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicDec(volatile int32_t* addr);
+/**
+ * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
+ *
+ * @param addr Address of value to decrement
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicDec(volatile uint32_t* addr);
+
+/**
+ * Atomic add a value to the value at addr. addr[0] += value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to add to the value at addr
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicAdd(volatile int32_t* addr, int32_t value);
+/**
+ * Atomic add a value to the value at addr. addr[0] += value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to add to the value at addr
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicAdd(volatile uint32_t* addr, uint32_t value);
+
+/**
+ * Atomic Subtract a value from the value at addr. addr[0] -= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to subtract from the value at addr
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicSub(volatile int32_t* addr, int32_t value);
+/**
+ * Atomic Subtract a value from the value at addr. addr[0] -= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to subtract from the value at addr
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicSub(volatile uint32_t* addr, uint32_t value);
+
+/**
+ * Atomic Bitwise and a value from the value at addr. addr[0] &= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to and with the value at addr
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicAnd(volatile int32_t* addr, int32_t value);
+/**
+ * Atomic Bitwise and a value from the value at addr. addr[0] &= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to and with the value at addr
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicAnd(volatile uint32_t* addr, uint32_t value);
+
+/**
+ * Atomic Bitwise or a value from the value at addr. addr[0] |= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to or with the value at addr
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicOr(volatile int32_t* addr, int32_t value);
+/**
+ * Atomic Bitwise or a value from the value at addr. addr[0] |= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to or with the value at addr
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicOr(volatile uint32_t* addr, uint32_t value);
+
+/**
+ * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to xor with the value at addr
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicXor(volatile uint32_t* addr, uint32_t value);
+/**
+ * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value
+ *
+ * @param addr Address of value to modify
+ * @param value Amount to xor with the value at addr
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicXor(volatile int32_t* addr, int32_t value);
+
+/**
+ * Atomic Set the value at addr to the min of addr and value
+ * addr[0] = rsMin(addr[0], value)
+ *
+ * @param addr Address of value to modify
+ * @param value comparison value
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicMin(volatile uint32_t* addr, uint32_t value);
+/**
+ * Atomic Set the value at addr to the min of addr and value
+ * addr[0] = rsMin(addr[0], value)
+ *
+ * @param addr Address of value to modify
+ * @param value comparison value
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicMin(volatile int32_t* addr, int32_t value);
+
+/**
+ * Atomic Set the value at addr to the max of addr and value
+ * addr[0] = rsMax(addr[0], value)
+ *
+ * @param addr Address of value to modify
+ * @param value comparison value
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicMax(volatile uint32_t* addr, uint32_t value);
+/**
+ * Atomic Set the value at addr to the max of addr and value
+ * addr[0] = rsMin(addr[0], value)
+ *
+ * @param addr Address of value to modify
+ * @param value comparison value
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicMax(volatile int32_t* addr, int32_t value);
+
+/**
+ * Compare-and-set operation with a full memory barrier.
+ *
+ * If the value at addr matches compareValue then newValue is written.
+ *
+ * @param addr The address to compare and replace if the compare passes.
+ * @param compareValue The value to test addr[0] against.
+ * @param newValue The value to write if the test passes.
+ *
+ * @return old value
+ */
+extern int32_t __attribute__((overloadable))
+ rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue);
+
+/**
+ * Compare-and-set operation with a full memory barrier.
+ *
+ * If the value at addr matches compareValue then newValue is written.
+ *
+ * @param addr The address to compare and replace if the compare passes.
+ * @param compareValue The value to test addr[0] against.
+ * @param newValue The value to write if the test passes.
+ *
+ * @return old value
+ */
+extern uint32_t __attribute__((overloadable))
+ rsAtomicCas(volatile uint32_t* addr, int32_t compareValue, int32_t newValue);
+
+
+#endif
+
diff --git a/libs/rs/scriptc/rs_cl.rsh b/libs/rs/scriptc/rs_cl.rsh
index d78e62e1d54a..e402b86864c9 100644
--- a/libs/rs/scriptc/rs_cl.rsh
+++ b/libs/rs/scriptc/rs_cl.rsh
@@ -1,8 +1,28 @@
+/*
+ * 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.
+ */
+
+/** @file rs_cl.rsh
+ * \brief Additional compute routines
+ *
+ *
+ */
+
#ifndef __RS_CL_RSH__
#define __RS_CL_RSH__
-#define _RS_RUNTIME extern
-
// Conversions
#define CVT_FUNC_2(typeout, typein) \
_RS_RUNTIME typeout##2 __attribute__((overloadable)) \
@@ -444,6 +464,5 @@ _RS_RUNTIME float4 __attribute__((overloadable)) normalize(float4 v);
#undef IN_FUNC_IN
#undef XN_FUNC_XN_XN_BODY
#undef IN_FUNC_IN_IN_BODY
-#undef _RS_RUNTIME
#endif
diff --git a/libs/rs/scriptc/rs_core.rsh b/libs/rs/scriptc/rs_core.rsh
index d939fb33d6ea..be900cb71f9c 100644
--- a/libs/rs/scriptc/rs_core.rsh
+++ b/libs/rs/scriptc/rs_core.rsh
@@ -1,579 +1,166 @@
+/*
+ * 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.
+ */
+
+/** @file rs_core.rsh
+ * \brief todo-jsams
+ *
+ * todo-jsams
+ *
+ */
+
#ifndef __RS_CORE_RSH__
#define __RS_CORE_RSH__
#define _RS_RUNTIME extern
+#include "rs_types.rsh"
+#include "rs_allocation.rsh"
+#include "rs_atomic.rsh"
+#include "rs_cl.rsh"
+#include "rs_debug.rsh"
+#include "rs_math.rsh"
+#include "rs_matrix.rsh"
+#include "rs_object.rsh"
+#include "rs_quaternion.rsh"
+#include "rs_time.rsh"
+
+
+
/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, float);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float, float);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, float, float, float, float);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, double);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix4x4 *);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix3x3 *);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, const rs_matrix2x2 *);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, int);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, uint);
-/**
- * Debug function. Prints a string and value to the log.
- */
-extern void __attribute__((overloadable))
- rsDebug(const char *, long);
-/**
- * Debug function. Prints a string and value to the log.
+ * Send a message back to the client. Will not block and returns true
+ * if the message was sendable and false if the fifo was full.
+ * A message ID is required. Data payload is optional.
*/
-extern void __attribute__((overloadable))
- rsDebug(const char *, unsigned long);
+extern bool __attribute__((overloadable))
+ rsSendToClient(int cmdID);
/**
- * Debug function. Prints a string and value to the log.
+ * \overload
*/
-extern void __attribute__((overloadable))
- rsDebug(const char *, long long);
+extern bool __attribute__((overloadable))
+ rsSendToClient(int cmdID, const void *data, uint len);
/**
- * Debug function. Prints a string and value to the log.
+ * Send a message back to the client, blocking until the message is queued.
+ * A message ID is required. Data payload is optional.
*/
extern void __attribute__((overloadable))
- rsDebug(const char *, unsigned long long);
+ rsSendToClientBlocking(int cmdID);
/**
- * Debug function. Prints a string and value to the log.
+ * \overload
*/
extern void __attribute__((overloadable))
- rsDebug(const char *, const void *);
-#define RS_DEBUG(a) rsDebug(#a, a)
-#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
+ rsSendToClientBlocking(int cmdID, const void *data, uint len);
/**
- * Debug function. Prints a string and value to the log.
- */
-_RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float2 v);
-/**
- * Debug function. Prints a string and value to the log.
- */
-_RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float3 v);
-/**
- * Debug function. Prints a string and value to the log.
- */
-_RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float4 v);
-
-
-/**
- * Pack floating point (0-1) RGB values into a uchar4. The alpha component is
- * set to 255 (1.0).
- *
- * @param r
- * @param g
- * @param b
+ * Launch order hint for rsForEach calls. This provides a hint to the system to
+ * determine in which order the root function of the target is called with each
+ * cell of the allocation.
*
- * @return uchar4
+ * This is a hint and implementations may not obey the order.
*/
-_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b);
+enum rs_for_each_strategy {
+ RS_FOR_EACH_STRATEGY_SERIAL,
+ RS_FOR_EACH_STRATEGY_DONT_CARE,
+ RS_FOR_EACH_STRATEGY_DST_LINEAR,
+ RS_FOR_EACH_STRATEGY_TILE_SMALL,
+ RS_FOR_EACH_STRATEGY_TILE_MEDIUM,
+ RS_FOR_EACH_STRATEGY_TILE_LARGE
+};
-/**
- * Pack floating point (0-1) RGBA values into a uchar4.
- *
- * @param r
- * @param g
- * @param b
- * @param a
- *
- * @return uchar4
- */
-_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a);
/**
- * Pack floating point (0-1) RGB values into a uchar4. The alpha component is
- * set to 255 (1.0).
- *
- * @param color
- *
- * @return uchar4
+ * Structure to provide extra information to a rsForEach call. Primarly used to
+ * restrict the call to a subset of cells in the allocation.
*/
-_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color);
+typedef struct rs_script_call {
+ enum rs_for_each_strategy strategy;
+ uint32_t xStart;
+ uint32_t xEnd;
+ uint32_t yStart;
+ uint32_t yEnd;
+ uint32_t zStart;
+ uint32_t zEnd;
+ uint32_t arrayStart;
+ uint32_t arrayEnd;
+} rs_script_call_t;
/**
- * Pack floating point (0-1) RGBA values into a uchar4.
+ * Make a script to script call to launch work. One of the input or output is
+ * required to be a valid object. The input and output must be of the same
+ * dimensions.
+ * API 10-13
*
- * @param color
+ * @param script The target script to call
+ * @param input The allocation to source data from
+ * @param output the allocation to write date into
+ * @param usrData The user definied params to pass to the root script. May be
+ * NULL.
+ * @param sc Extra control infomation used to select a sub-region of the
+ * allocation to be processed or suggest a walking strategy. May be
+ * NULL.
*
- * @return uchar4
- */
-_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color);
-
-/**
- * Unpack a uchar4 color to float4. The resulting float range will be (0-1).
- *
- * @param c
- *
- * @return float4
- */
-_RS_RUNTIME float4 rsUnpackColor8888(uchar4 c);
-
-
-/////////////////////////////////////////////////////
-// Matrix ops
-/////////////////////////////////////////////////////
-
+ * */
+#if !defined(RS_VERSION) || (RS_VERSION < 14)
+extern void __attribute__((overloadable))
+ rsForEach(rs_script script, rs_allocation input,
+ rs_allocation output, const void * usrData,
+ const rs_script_call_t *sc);
/**
- * Set one element of a matrix.
- *
- * @param m The matrix to be set
- * @param row
- * @param col
- * @param v
- *
- * @return void
+ * \overload
*/
-_RS_RUNTIME void __attribute__((overloadable))
-rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v);
-_RS_RUNTIME void __attribute__((overloadable))
-rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v);
-_RS_RUNTIME void __attribute__((overloadable))
-rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v);
+extern void __attribute__((overloadable))
+ rsForEach(rs_script script, rs_allocation input,
+ rs_allocation output, const void * usrData);
+#else
/**
- * Get one element of a matrix.
- *
- * @param m The matrix to read from
- * @param row
- * @param col
+ * Make a script to script call to launch work. One of the input or output is
+ * required to be a valid object. The input and output must be of the same
+ * dimensions.
+ * API 14+
*
- * @return float
- */
-_RS_RUNTIME float __attribute__((overloadable))
-rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col);
-_RS_RUNTIME float __attribute__((overloadable))
-rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col);
-_RS_RUNTIME float __attribute__((overloadable))
-rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col);
-
-/**
- * Set the elements of a matrix to the identity matrix.
+ * @param script The target script to call
+ * @param input The allocation to source data from
+ * @param output the allocation to write date into
+ * @param usrData The user definied params to pass to the root script. May be
+ * NULL.
+ * @param usrDataLen The size of the userData structure. This will be used to
+ * perform a shallow copy of the data if necessary.
+ * @param sc Extra control infomation used to select a sub-region of the
+ * allocation to be processed or suggest a walking strategy. May be
+ * NULL.
*
- * @param m
*/
-extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m);
-extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m);
-extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m);
-
-/**
- * Set the elements of a matrix from an array of floats.
- *
- * @param m
- */
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v);
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v);
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v);
-
+extern void __attribute__((overloadable))
+ rsForEach(rs_script script, rs_allocation input, rs_allocation output,
+ const void * usrData, size_t usrDataLen, const rs_script_call_t *);
/**
- * Set the elements of a matrix from another matrix.
- *
- * @param m
+ * \overload
*/
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v);
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v);
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v);
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v);
-extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v);
-
+extern void __attribute__((overloadable))
+ rsForEach(rs_script script, rs_allocation input, rs_allocation output,
+ const void * usrData, size_t usrDataLen);
/**
- * Load a rotation matrix.
- *
- * @param m
- * @param rot
- * @param x
- * @param y
- * @param z
+ * \overload
*/
extern void __attribute__((overloadable))
-rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs);
-
-extern void __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs);
-
-extern void __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs);
-
-extern void __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs);
-
-extern void __attribute__((overloadable))
-rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
-
-extern void __attribute__((overloadable))
-rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z);
-
-extern void __attribute__((overloadable))
-rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
-
-extern void __attribute__((overloadable))
-rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
-
-#if !defined(RS_VERSION) || (RS_VERSION < 14)
-_RS_RUNTIME float4 __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix4x4 *m, float4 in);
-
-_RS_RUNTIME float4 __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix4x4 *m, float3 in);
-
-_RS_RUNTIME float4 __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix4x4 *m, float2 in);
-
-_RS_RUNTIME float3 __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix3x3 *m, float3 in);
-
-_RS_RUNTIME float3 __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix3x3 *m, float2 in);
-
-_RS_RUNTIME float2 __attribute__((overloadable))
-rsMatrixMultiply(rs_matrix2x2 *m, float2 in);
-#else
-_RS_RUNTIME float4 __attribute__((overloadable))
-rsMatrixMultiply(const rs_matrix4x4 *m, float4 in);
-
-_RS_RUNTIME float4 __attribute__((overloadable))
-rsMatrixMultiply(const rs_matrix4x4 *m, float3 in);
-
-_RS_RUNTIME float4 __attribute__((overloadable))
-rsMatrixMultiply(const rs_matrix4x4 *m, float2 in);
-
-_RS_RUNTIME float3 __attribute__((overloadable))
-rsMatrixMultiply(const rs_matrix3x3 *m, float3 in);
-
-_RS_RUNTIME float3 __attribute__((overloadable))
-rsMatrixMultiply(const rs_matrix3x3 *m, float2 in);
-
-_RS_RUNTIME float2 __attribute__((overloadable))
-rsMatrixMultiply(const rs_matrix2x2 *m, float2 in);
+ rsForEach(rs_script script, rs_allocation input, rs_allocation output);
#endif
-// Returns true if the matrix was successfully inversed
-extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m);
-extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m);
-extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m);
-extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m);
-extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m);
-
-/////////////////////////////////////////////////////
-// quaternion ops
-/////////////////////////////////////////////////////
-
-static void __attribute__((overloadable))
-rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
- q->w = w;
- q->x = x;
- q->y = y;
- q->z = z;
-}
-
-static void __attribute__((overloadable))
-rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
- q->w = rhs->w;
- q->x = rhs->x;
- q->y = rhs->y;
- q->z = rhs->z;
-}
-
-static void __attribute__((overloadable))
-rsQuaternionMultiply(rs_quaternion *q, float s) {
- q->w *= s;
- q->x *= s;
- q->y *= s;
- q->z *= s;
-}
-
-static void __attribute__((overloadable))
-rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
- q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
- q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
- q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
- q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
-}
-
-static void
-rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
- q->w *= rhs->w;
- q->x *= rhs->x;
- q->y *= rhs->y;
- q->z *= rhs->z;
-}
-
-static void
-rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
- rot *= (float)(M_PI / 180.0f) * 0.5f;
- float c = cos(rot);
- float s = sin(rot);
-
- q->w = c;
- q->x = x * s;
- q->y = y * s;
- q->z = z * s;
-}
-
-static void
-rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
- const float len = x*x + y*y + z*z;
- if (len != 1) {
- const float recipLen = 1.f / sqrt(len);
- x *= recipLen;
- y *= recipLen;
- z *= recipLen;
- }
- rsQuaternionLoadRotateUnit(q, rot, x, y, z);
-}
-
-static void
-rsQuaternionConjugate(rs_quaternion *q) {
- q->x = -q->x;
- q->y = -q->y;
- q->z = -q->z;
-}
-
-static float
-rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
- return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
-}
-
-static void
-rsQuaternionNormalize(rs_quaternion *q) {
- const float len = rsQuaternionDot(q, q);
- if (len != 1) {
- const float recipLen = 1.f / sqrt(len);
- rsQuaternionMultiply(q, recipLen);
- }
-}
-
-static void
-rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
- if (t <= 0.0f) {
- rsQuaternionSet(q, q0);
- return;
- }
- if (t >= 1.0f) {
- rsQuaternionSet(q, q1);
- return;
- }
-
- rs_quaternion tempq0, tempq1;
- rsQuaternionSet(&tempq0, q0);
- rsQuaternionSet(&tempq1, q1);
-
- float angle = rsQuaternionDot(q0, q1);
- if (angle < 0) {
- rsQuaternionMultiply(&tempq0, -1.0f);
- angle *= -1.0f;
- }
-
- float scale, invScale;
- if (angle + 1.0f > 0.05f) {
- if (1.0f - angle >= 0.05f) {
- float theta = acos(angle);
- float invSinTheta = 1.0f / sin(theta);
- scale = sin(theta * (1.0f - t)) * invSinTheta;
- invScale = sin(theta * t) * invSinTheta;
- } else {
- scale = 1.0f - t;
- invScale = t;
- }
- } else {
- rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
- scale = sin(M_PI * (0.5f - t));
- invScale = sin(M_PI * t);
- }
-
- rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
- tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
-}
-
-static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
- float x2 = 2.0f * q->x * q->x;
- float y2 = 2.0f * q->y * q->y;
- float z2 = 2.0f * q->z * q->z;
- float xy = 2.0f * q->x * q->y;
- float wz = 2.0f * q->w * q->z;
- float xz = 2.0f * q->x * q->z;
- float wy = 2.0f * q->w * q->y;
- float wx = 2.0f * q->w * q->x;
- float yz = 2.0f * q->y * q->z;
-
- m->m[0] = 1.0f - y2 - z2;
- m->m[1] = xy - wz;
- m->m[2] = xz + wy;
- m->m[3] = 0.0f;
-
- m->m[4] = xy + wz;
- m->m[5] = 1.0f - x2 - z2;
- m->m[6] = yz - wx;
- m->m[7] = 0.0f;
-
- m->m[8] = xz - wy;
- m->m[9] = yz - wx;
- m->m[10] = 1.0f - x2 - y2;
- m->m[11] = 0.0f;
-
- m->m[12] = 0.0f;
- m->m[13] = 0.0f;
- m->m[14] = 0.0f;
- m->m[15] = 1.0f;
-}
-
-/////////////////////////////////////////////////////
-// utility funcs
-/////////////////////////////////////////////////////
-__inline__ static void __attribute__((overloadable, always_inline))
-rsExtractFrustumPlanes(const rs_matrix4x4 *modelViewProj,
- float4 *left, float4 *right,
- float4 *top, float4 *bottom,
- float4 *near, float4 *far) {
- // x y z w = a b c d in the plane equation
- left->x = modelViewProj->m[3] + modelViewProj->m[0];
- left->y = modelViewProj->m[7] + modelViewProj->m[4];
- left->z = modelViewProj->m[11] + modelViewProj->m[8];
- left->w = modelViewProj->m[15] + modelViewProj->m[12];
-
- right->x = modelViewProj->m[3] - modelViewProj->m[0];
- right->y = modelViewProj->m[7] - modelViewProj->m[4];
- right->z = modelViewProj->m[11] - modelViewProj->m[8];
- right->w = modelViewProj->m[15] - modelViewProj->m[12];
-
- top->x = modelViewProj->m[3] - modelViewProj->m[1];
- top->y = modelViewProj->m[7] - modelViewProj->m[5];
- top->z = modelViewProj->m[11] - modelViewProj->m[9];
- top->w = modelViewProj->m[15] - modelViewProj->m[13];
-
- bottom->x = modelViewProj->m[3] + modelViewProj->m[1];
- bottom->y = modelViewProj->m[7] + modelViewProj->m[5];
- bottom->z = modelViewProj->m[11] + modelViewProj->m[9];
- bottom->w = modelViewProj->m[15] + modelViewProj->m[13];
-
- near->x = modelViewProj->m[3] + modelViewProj->m[2];
- near->y = modelViewProj->m[7] + modelViewProj->m[6];
- near->z = modelViewProj->m[11] + modelViewProj->m[10];
- near->w = modelViewProj->m[15] + modelViewProj->m[14];
-
- far->x = modelViewProj->m[3] - modelViewProj->m[2];
- far->y = modelViewProj->m[7] - modelViewProj->m[6];
- far->z = modelViewProj->m[11] - modelViewProj->m[10];
- far->w = modelViewProj->m[15] - modelViewProj->m[14];
-
- float len = length(left->xyz);
- *left /= len;
- len = length(right->xyz);
- *right /= len;
- len = length(top->xyz);
- *top /= len;
- len = length(bottom->xyz);
- *bottom /= len;
- len = length(near->xyz);
- *near /= len;
- len = length(far->xyz);
- *far /= len;
-}
-
-__inline__ static bool __attribute__((overloadable, always_inline))
-rsIsSphereInFrustum(float4 *sphere,
- float4 *left, float4 *right,
- float4 *top, float4 *bottom,
- float4 *near, float4 *far) {
-
- float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
- if (distToCenter < -sphere->w) {
- return false;
- }
- distToCenter = dot(right->xyz, sphere->xyz) + right->w;
- if (distToCenter < -sphere->w) {
- return false;
- }
- distToCenter = dot(top->xyz, sphere->xyz) + top->w;
- if (distToCenter < -sphere->w) {
- return false;
- }
- distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
- if (distToCenter < -sphere->w) {
- return false;
- }
- distToCenter = dot(near->xyz, sphere->xyz) + near->w;
- if (distToCenter < -sphere->w) {
- return false;
- }
- distToCenter = dot(far->xyz, sphere->xyz) + far->w;
- if (distToCenter < -sphere->w) {
- return false;
- }
- return true;
-}
-
-
-/////////////////////////////////////////////////////
-// int ops
-/////////////////////////////////////////////////////
-_RS_RUNTIME uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high);
-_RS_RUNTIME int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high);
-_RS_RUNTIME ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high);
-_RS_RUNTIME short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high);
-_RS_RUNTIME uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high);
-_RS_RUNTIME char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high);
#undef _RS_RUNTIME
diff --git a/libs/rs/scriptc/rs_debug.rsh b/libs/rs/scriptc/rs_debug.rsh
new file mode 100644
index 000000000000..074c28fe70ab
--- /dev/null
+++ b/libs/rs/scriptc/rs_debug.rsh
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+/** @file rs_debug.rsh
+ * \brief Utility debugging routines
+ *
+ * Routines intended to be used during application developement. These should
+ * not be used in shipping applications. All print a string and value pair to
+ * the standard log.
+ *
+ */
+
+#ifndef __RS_DEBUG_RSH__
+#define __RS_DEBUG_RSH__
+
+
+
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float, float);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, float, float, float, float);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, double);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix4x4 *);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix3x3 *);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const rs_matrix2x2 *);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, int);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, uint);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, long);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, unsigned long);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, long long);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, unsigned long long);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+extern void __attribute__((overloadable))
+ rsDebug(const char *, const void *);
+#define RS_DEBUG(a) rsDebug(#a, a)
+#define RS_DEBUG_MARKER rsDebug(__FILE__, __LINE__)
+
+
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+_RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float2 v);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+_RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float3 v);
+/**
+ * Debug function. Prints a string and value to the log.
+ */
+_RS_RUNTIME void __attribute__((overloadable)) rsDebug(const char *s, float4 v);
+
+#endif
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 9a8a4e66a03d..00fd1b10f53f 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -1,3 +1,25 @@
+/*
+ * 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.
+ */
+
+/** @file rs_graphics.rsh
+ * \brief Renderscript graphics API
+ *
+ * A set of graphics functions used by Renderscript.
+ *
+ */
#ifndef __RS_GRAPHICS_RSH__
#define __RS_GRAPHICS_RSH__
@@ -37,7 +59,7 @@ extern void __attribute__((overloadable))
rsgClearAllRenderTargets(void);
/**
- * Force RenderScript to finish all rendering commands
+ * Force Renderscript to finish all rendering commands
*/
extern uint __attribute__((overloadable))
rsgFinish(void);
@@ -94,16 +116,38 @@ extern void __attribute__((overloadable))
extern void __attribute__((overloadable))
rsgBindTexture(rs_program_fragment, uint slot, rs_allocation);
-
+/**
+ * Load the projection matrix for a currently bound fixed function
+ * vertex program. Calling this function with a custom vertex shader
+ * would result in an error.
+ * @param proj projection matrix
+ */
extern void __attribute__((overloadable))
- rsgProgramVertexLoadProjectionMatrix(const rs_matrix4x4 *);
+ rsgProgramVertexLoadProjectionMatrix(const rs_matrix4x4 *proj);
+/**
+ * Load the model matrix for a currently bound fixed function
+ * vertex program. Calling this function with a custom vertex shader
+ * would result in an error.
+ * @param model model matrix
+ */
extern void __attribute__((overloadable))
- rsgProgramVertexLoadModelMatrix(const rs_matrix4x4 *);
+ rsgProgramVertexLoadModelMatrix(const rs_matrix4x4 *model);
+/**
+ * Load the texture matrix for a currently bound fixed function
+ * vertex program. Calling this function with a custom vertex shader
+ * would result in an error.
+ * @param tex texture matrix
+ */
extern void __attribute__((overloadable))
- rsgProgramVertexLoadTextureMatrix(const rs_matrix4x4 *);
-
+ rsgProgramVertexLoadTextureMatrix(const rs_matrix4x4 *tex);
+/**
+ * Get the projection matrix for a currently bound fixed function
+ * vertex program. Calling this function with a custom vertex shader
+ * would result in an error.
+ * @param proj matrix to store the current projection matrix into
+ */
extern void __attribute__((overloadable))
- rsgProgramVertexGetProjectionMatrix(rs_matrix4x4 *);
+ rsgProgramVertexGetProjectionMatrix(rs_matrix4x4 *proj);
/**
* Set the constant color for a fixed function emulation program.
@@ -239,15 +283,29 @@ extern void __attribute__((overloadable))
rsgDrawSpriteScreenspace(float x, float y, float z, float w, float h);
/**
- * Draw a mesh of geometry using the current context state. The whole mesh is
+ * Draw a mesh using the current context state. The whole mesh is
* rendered.
*
* @param ism
*/
extern void __attribute__((overloadable))
rsgDrawMesh(rs_mesh ism);
+/**
+ * Draw part of a mesh using the current context state.
+ * @param ism mesh object to render
+ * @param primitiveIndex for meshes that contain multiple primitive groups
+ * this parameter specifies the index of the group to draw.
+ */
extern void __attribute__((overloadable))
rsgDrawMesh(rs_mesh ism, uint primitiveIndex);
+/**
+ * Draw specified index range of part of a mesh using the current context state.
+ * @param ism mesh object to render
+ * @param primitiveIndex for meshes that contain multiple primitive groups
+ * this parameter specifies the index of the group to draw.
+ * @param start starting index in the range
+ * @param len number of indices to draw
+ */
extern void __attribute__((overloadable))
rsgDrawMesh(rs_mesh ism, uint primitiveIndex, uint start, uint len);
@@ -264,29 +322,54 @@ extern void __attribute__((overloadable))
/**
* Clears the depth suface to the specified value.
- *
*/
extern void __attribute__((overloadable))
rsgClearDepth(float value);
-
+/**
+ * Draws text given a string and location
+ */
extern void __attribute__((overloadable))
rsgDrawText(const char *, int x, int y);
+/**
+ * \overload
+ */
extern void __attribute__((overloadable))
rsgDrawText(rs_allocation, int x, int y);
+/**
+ * Binds the font object to be used for all subsequent font rendering calls
+ * @param font object to bind
+ */
extern void __attribute__((overloadable))
- rsgBindFont(rs_font);
+ rsgBindFont(rs_font font);
+/**
+ * Sets the font color for all subsequent rendering calls
+ * @param r red component
+ * @param g green component
+ * @param b blue component
+ * @param a alpha component
+ */
extern void __attribute__((overloadable))
- rsgFontColor(float, float, float, float);
-// Returns the bounding box of the text relative to (0, 0)
-// Any of left, right, top, bottom could be NULL
+ rsgFontColor(float r, float g, float b, float a);
+/**
+ * Returns the bounding box of the text relative to (0, 0)
+ * Any of left, right, top, bottom could be NULL
+ */
extern void __attribute__((overloadable))
rsgMeasureText(const char *, int *left, int *right, int *top, int *bottom);
+/**
+ * \overload
+ */
extern void __attribute__((overloadable))
rsgMeasureText(rs_allocation, int *left, int *right, int *top, int *bottom);
-
+/**
+ * Computes an axis aligned bounding box of a mesh object
+ */
extern void __attribute__((overloadable))
rsgMeshComputeBoundingBox(rs_mesh mesh, float *minX, float *minY, float *minZ,
float *maxX, float *maxY, float *maxZ);
+/**
+ * \overload
+ */
__inline__ static void __attribute__((overloadable, always_inline))
rsgMeshComputeBoundingBox(rs_mesh mesh, float3 *bBoxMin, float3 *bBoxMax) {
float x1, y1, z1, x2, y2, z2;
diff --git a/libs/rs/scriptc/rs_math.rsh b/libs/rs/scriptc/rs_math.rsh
index 1d36cc6530aa..8117ca824b18 100644
--- a/libs/rs/scriptc/rs_math.rsh
+++ b/libs/rs/scriptc/rs_math.rsh
@@ -1,495 +1,248 @@
-#ifndef __RS_MATH_RSH__
-#define __RS_MATH_RSH__
-
-/**
- * Copy reference to the specified object.
- *
- * @param dst
- * @param src
- */
-extern void __attribute__((overloadable))
- rsSetObject(rs_element *dst, rs_element src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_type *dst, rs_type src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_allocation *dst, rs_allocation src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_sampler *dst, rs_sampler src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_script *dst, rs_script src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_mesh *dst, rs_mesh src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_program_fragment *dst, rs_program_fragment src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_program_vertex *dst, rs_program_vertex src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_program_raster *dst, rs_program_raster src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_program_store *dst, rs_program_store src);
-extern void __attribute__((overloadable))
- rsSetObject(rs_font *dst, rs_font src);
-
-/**
- * Sets the object to NULL.
+/*
+ * Copyright (C) 2011 The Android Open Source Project
*
- * @return bool
- */
-extern void __attribute__((overloadable))
- rsClearObject(rs_element *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_type *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_allocation *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_sampler *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_script *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_mesh *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_program_fragment *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_program_vertex *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_program_raster *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_program_store *dst);
-extern void __attribute__((overloadable))
- rsClearObject(rs_font *dst);
-
-/**
- * Tests if the object is valid. Returns true if the object is valid, false if
- * it is NULL.
- *
- * @return bool
- */
-extern bool __attribute__((overloadable))
- rsIsObject(rs_element);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_type);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_allocation);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_sampler);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_script);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_mesh);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_program_fragment);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_program_vertex);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_program_raster);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_program_store);
-extern bool __attribute__((overloadable))
- rsIsObject(rs_font);
-
-
-/**
- * Returns the Allocation for a given pointer. The pointer should point within
- * a valid allocation. The results are undefined if the pointer is not from a
- * valid allocation.
- */
-extern rs_allocation __attribute__((overloadable))
- rsGetAllocation(const void *);
-
-/**
- * Query the dimension of an allocation.
+ * 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
*
- * @return uint32_t The X dimension of the allocation.
- */
-extern uint32_t __attribute__((overloadable))
- rsAllocationGetDimX(rs_allocation);
-
-/**
- * Query the dimension of an allocation.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * @return uint32_t The Y dimension of the allocation.
+ * 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.
*/
-extern uint32_t __attribute__((overloadable))
- rsAllocationGetDimY(rs_allocation);
-/**
- * Query the dimension of an allocation.
+/** @file rs_math.rsh
+ * \brief todo-jsams
*
- * @return uint32_t The Z dimension of the allocation.
- */
-extern uint32_t __attribute__((overloadable))
- rsAllocationGetDimZ(rs_allocation);
-
-/**
- * Query an allocation for the presence of more than one LOD.
+ * todo-jsams
*
- * @return uint32_t Returns 1 if more than one LOD is present, 0 otherwise.
*/
-extern uint32_t __attribute__((overloadable))
- rsAllocationGetDimLOD(rs_allocation);
-/**
- * Query an allocation for the presence of more than one face.
- *
- * @return uint32_t Returns 1 if more than one face is present, 0 otherwise.
- */
-extern uint32_t __attribute__((overloadable))
- rsAllocationGetDimFaces(rs_allocation);
+#ifndef __RS_MATH_RSH__
+#define __RS_MATH_RSH__
-/**
- * Copy part of an allocation from another allocation.
- *
- * @param dstAlloc Allocation to copy data into.
- * @param dstOff The offset of the first element to be copied in
- * the destination allocation.
- * @param dstMip Mip level in the destination allocation.
- * @param count The number of elements to be copied.
- * @param srcAlloc The source data allocation.
- * @param srcOff The offset of the first element in data to be
- * copied in the source allocation.
- * @param srcMip Mip level in the source allocation.
- */
-extern void __attribute__((overloadable))
- rsAllocationCopy1DRange(rs_allocation dstAlloc,
- uint32_t dstOff, uint32_t dstMip,
- uint32_t count,
- rs_allocation srcAlloc,
- uint32_t srcOff, uint32_t srcMip);
/**
- * Copy a rectangular region into the allocation from another
- * allocation.
- *
- * @param dstAlloc allocation to copy data into.
- * @param dstXoff X offset of the region to update in the
- * destination allocation.
- * @param dstYoff Y offset of the region to update in the
- * destination allocation.
- * @param dstMip Mip level in the destination allocation.
- * @param dstFace Cubemap face of the destination allocation,
- * ignored for allocations that aren't cubemaps.
- * @param width Width of the incoming region to update.
- * @param height Height of the incoming region to update.
- * @param srcAlloc The source data allocation.
- * @param srcXoff X offset in data of the source allocation.
- * @param srcYoff Y offset in data of the source allocation.
- * @param srcMip Mip level in the source allocation.
- * @param srcFace Cubemap face of the source allocation,
- * ignored for allocations that aren't cubemaps.
+ * Return a random value between 0 (or min_value) and max_malue.
*/
-extern void __attribute__((overloadable))
- rsAllocationCopy2DRange(rs_allocation dstAlloc,
- uint32_t dstXoff, uint32_t dstYoff,
- uint32_t dstMip,
- rs_allocation_cubemap_face dstFace,
- uint32_t width, uint32_t height,
- rs_allocation srcAlloc,
- uint32_t srcXoff, uint32_t srcYoff,
- uint32_t srcMip,
- rs_allocation_cubemap_face srcFace);
-
-// Extract a single element from an allocation.
-extern const void * __attribute__((overloadable))
- rsGetElementAt(rs_allocation, uint32_t x);
-extern const void * __attribute__((overloadable))
- rsGetElementAt(rs_allocation, uint32_t x, uint32_t y);
-extern const void * __attribute__((overloadable))
- rsGetElementAt(rs_allocation, uint32_t x, uint32_t y, uint32_t z);
-
-// Return a random value between 0 (or min_value) and max_malue.
extern int __attribute__((overloadable))
rsRand(int max_value);
+/**
+ * \overload
+ */
extern int __attribute__((overloadable))
rsRand(int min_value, int max_value);
+/**
+ * \overload
+ */
extern float __attribute__((overloadable))
rsRand(float max_value);
+/**
+ * \overload
+ */
extern float __attribute__((overloadable))
rsRand(float min_value, float max_value);
-// return the fractional part of a float
-// min(v - ((int)floor(v)), 0x1.fffffep-1f);
+/**
+ * Returns the fractional part of a float
+ */
extern float __attribute__((overloadable))
rsFrac(float);
-// Send a message back to the client. Will not block and returns true
-// if the message was sendable and false if the fifo was full.
-// A message ID is required. Data payload is optional.
-extern bool __attribute__((overloadable))
- rsSendToClient(int cmdID);
-extern bool __attribute__((overloadable))
- rsSendToClient(int cmdID, const void *data, uint len);
-
-// Send a message back to the client, blocking until the message is queued.
-// A message ID is required. Data payload is optional.
-extern void __attribute__((overloadable))
- rsSendToClientBlocking(int cmdID);
-extern void __attribute__((overloadable))
- rsSendToClientBlocking(int cmdID, const void *data, uint len);
-
-
-// Script to Script
-enum rs_for_each_strategy {
- RS_FOR_EACH_STRATEGY_SERIAL,
- RS_FOR_EACH_STRATEGY_DONT_CARE,
- RS_FOR_EACH_STRATEGY_DST_LINEAR,
- RS_FOR_EACH_STRATEGY_TILE_SMALL,
- RS_FOR_EACH_STRATEGY_TILE_MEDIUM,
- RS_FOR_EACH_STRATEGY_TILE_LARGE
-};
-
-typedef struct rs_script_call {
- enum rs_for_each_strategy strategy;
- uint32_t xStart;
- uint32_t xEnd;
- uint32_t yStart;
- uint32_t yEnd;
- uint32_t zStart;
- uint32_t zEnd;
- uint32_t arrayStart;
- uint32_t arrayEnd;
-} rs_script_call_t;
-#if !defined(RS_VERSION) || (RS_VERSION < 14)
-extern void __attribute__((overloadable))
- rsForEach(rs_script script, rs_allocation input,
- rs_allocation output, const void * usrData,
- const rs_script_call_t *);
+/////////////////////////////////////////////////////
+// int ops
+/////////////////////////////////////////////////////
-extern void __attribute__((overloadable))
- rsForEach(rs_script script, rs_allocation input,
- rs_allocation output, const void * usrData);
-#else
-extern void __attribute__((overloadable))
- rsForEach(rs_script script, rs_allocation input, rs_allocation output);
-
-extern void __attribute__((overloadable))
- rsForEach(rs_script script, rs_allocation input, rs_allocation output,
- const void * usrData, size_t usrDataLen);
-
-extern void __attribute__((overloadable))
- rsForEach(rs_script script, rs_allocation input, rs_allocation output,
- const void * usrData, size_t usrDataLen, const rs_script_call_t *);
-#endif
-
-
-/**
- * Atomic add one to the value at addr.
- * Equal to rsAtomicAdd(addr, 1)
- *
- * @param addr Address of value to increment
- *
- * @return old value
- */
-extern int32_t __attribute__((overloadable))
- rsAtomicInc(volatile int32_t* addr);
/**
- * Atomic add one to the value at addr.
- * Equal to rsAtomicAdd(addr, 1)
- *
- * @param addr Address of value to increment
+ * Clamp the value amount between low and high.
*
- * @return old value
+ * @param amount The value to clamp
+ * @param low
+ * @param high
*/
-extern uint32_t __attribute__((overloadable))
- rsAtomicInc(volatile uint32_t* addr);
+_RS_RUNTIME uint __attribute__((overloadable, always_inline)) rsClamp(uint amount, uint low, uint high);
/**
- * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
- *
- * @param addr Address of value to decrement
- *
- * @return old value
- */
-extern int32_t __attribute__((overloadable))
- rsAtomicDec(volatile int32_t* addr);
-/**
- * Atomic subtract one from the value at addr. Equal to rsAtomicSub(addr, 1)
- *
- * @param addr Address of value to decrement
- *
- * @return old value
+ * \overload
*/
-extern uint32_t __attribute__((overloadable))
- rsAtomicDec(volatile uint32_t* addr);
-
+_RS_RUNTIME int __attribute__((overloadable, always_inline)) rsClamp(int amount, int low, int high);
/**
- * Atomic add a value to the value at addr. addr[0] += value
- *
- * @param addr Address of value to modify
- * @param value Amount to add to the value at addr
- *
- * @return old value
+ * \overload
*/
-extern int32_t __attribute__((overloadable))
- rsAtomicAdd(volatile int32_t* addr, int32_t value);
+_RS_RUNTIME ushort __attribute__((overloadable, always_inline)) rsClamp(ushort amount, ushort low, ushort high);
/**
- * Atomic add a value to the value at addr. addr[0] += value
- *
- * @param addr Address of value to modify
- * @param value Amount to add to the value at addr
- *
- * @return old value
+ * \overload
*/
-extern uint32_t __attribute__((overloadable))
- rsAtomicAdd(volatile uint32_t* addr, uint32_t value);
+_RS_RUNTIME short __attribute__((overloadable, always_inline)) rsClamp(short amount, short low, short high);
+/**
+ * \overload
+ */
+_RS_RUNTIME uchar __attribute__((overloadable, always_inline)) rsClamp(uchar amount, uchar low, uchar high);
+/**
+ * \overload
+ */
+_RS_RUNTIME char __attribute__((overloadable, always_inline)) rsClamp(char amount, char low, char high);
+
+
+/**
+ * Computes 6 frustum planes from the view projection matrix
+ * @param viewProj matrix to extract planes from
+ * @param left plane
+ * @param right plane
+ * @param top plane
+ * @param bottom plane
+ * @param near plane
+ * @param far plane
+ */
+__inline__ static void __attribute__((overloadable, always_inline))
+rsExtractFrustumPlanes(const rs_matrix4x4 *viewProj,
+ float4 *left, float4 *right,
+ float4 *top, float4 *bottom,
+ float4 *near, float4 *far) {
+ // x y z w = a b c d in the plane equation
+ left->x = viewProj->m[3] + viewProj->m[0];
+ left->y = viewProj->m[7] + viewProj->m[4];
+ left->z = viewProj->m[11] + viewProj->m[8];
+ left->w = viewProj->m[15] + viewProj->m[12];
-/**
- * Atomic Subtract a value from the value at addr. addr[0] -= value
- *
- * @param addr Address of value to modify
- * @param value Amount to subtract from the value at addr
- *
- * @return old value
- */
-extern int32_t __attribute__((overloadable))
- rsAtomicSub(volatile int32_t* addr, int32_t value);
-/**
- * Atomic Subtract a value from the value at addr. addr[0] -= value
- *
- * @param addr Address of value to modify
- * @param value Amount to subtract from the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
- rsAtomicSub(volatile uint32_t* addr, uint32_t value);
+ right->x = viewProj->m[3] - viewProj->m[0];
+ right->y = viewProj->m[7] - viewProj->m[4];
+ right->z = viewProj->m[11] - viewProj->m[8];
+ right->w = viewProj->m[15] - viewProj->m[12];
-/**
- * Atomic Bitwise and a value from the value at addr. addr[0] &= value
- *
- * @param addr Address of value to modify
- * @param value Amount to and with the value at addr
- *
- * @return old value
- */
-extern int32_t __attribute__((overloadable))
- rsAtomicAnd(volatile int32_t* addr, int32_t value);
-/**
- * Atomic Bitwise and a value from the value at addr. addr[0] &= value
- *
- * @param addr Address of value to modify
- * @param value Amount to and with the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
- rsAtomicAnd(volatile uint32_t* addr, uint32_t value);
+ top->x = viewProj->m[3] - viewProj->m[1];
+ top->y = viewProj->m[7] - viewProj->m[5];
+ top->z = viewProj->m[11] - viewProj->m[9];
+ top->w = viewProj->m[15] - viewProj->m[13];
-/**
- * Atomic Bitwise or a value from the value at addr. addr[0] |= value
- *
- * @param addr Address of value to modify
- * @param value Amount to or with the value at addr
- *
- * @return old value
- */
-extern int32_t __attribute__((overloadable))
- rsAtomicOr(volatile int32_t* addr, int32_t value);
-/**
- * Atomic Bitwise or a value from the value at addr. addr[0] |= value
- *
- * @param addr Address of value to modify
- * @param value Amount to or with the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
- rsAtomicOr(volatile uint32_t* addr, uint32_t value);
+ bottom->x = viewProj->m[3] + viewProj->m[1];
+ bottom->y = viewProj->m[7] + viewProj->m[5];
+ bottom->z = viewProj->m[11] + viewProj->m[9];
+ bottom->w = viewProj->m[15] + viewProj->m[13];
-/**
- * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value
- *
- * @param addr Address of value to modify
- * @param value Amount to xor with the value at addr
- *
- * @return old value
- */
-extern uint32_t __attribute__((overloadable))
- rsAtomicXor(volatile uint32_t* addr, uint32_t value);
-/**
- * Atomic Bitwise xor a value from the value at addr. addr[0] ^= value
- *
- * @param addr Address of value to modify
- * @param value Amount to xor with the value at addr
- *
- * @return old value
- */
-extern int32_t __attribute__((overloadable))
- rsAtomicXor(volatile int32_t* addr, int32_t value);
+ near->x = viewProj->m[3] + viewProj->m[2];
+ near->y = viewProj->m[7] + viewProj->m[6];
+ near->z = viewProj->m[11] + viewProj->m[10];
+ near->w = viewProj->m[15] + viewProj->m[14];
+
+ far->x = viewProj->m[3] - viewProj->m[2];
+ far->y = viewProj->m[7] - viewProj->m[6];
+ far->z = viewProj->m[11] - viewProj->m[10];
+ far->w = viewProj->m[15] - viewProj->m[14];
+
+ float len = length(left->xyz);
+ *left /= len;
+ len = length(right->xyz);
+ *right /= len;
+ len = length(top->xyz);
+ *top /= len;
+ len = length(bottom->xyz);
+ *bottom /= len;
+ len = length(near->xyz);
+ *near /= len;
+ len = length(far->xyz);
+ *far /= len;
+}
/**
- * Atomic Set the value at addr to the min of addr and value
- * addr[0] = rsMin(addr[0], value)
- *
- * @param addr Address of value to modify
- * @param value comparison value
- *
- * @return old value
+ * Checks if a sphere is withing the 6 frustum planes
+ * @param sphere float4 representing the sphere
+ * @param left plane
+ * @param right plane
+ * @param top plane
+ * @param bottom plane
+ * @param near plane
+ * @param far plane
*/
-extern uint32_t __attribute__((overloadable))
- rsAtomicMin(volatile uint32_t* addr, uint32_t value);
+__inline__ static bool __attribute__((overloadable, always_inline))
+rsIsSphereInFrustum(float4 *sphere,
+ float4 *left, float4 *right,
+ float4 *top, float4 *bottom,
+ float4 *near, float4 *far) {
+
+ float distToCenter = dot(left->xyz, sphere->xyz) + left->w;
+ if (distToCenter < -sphere->w) {
+ return false;
+ }
+ distToCenter = dot(right->xyz, sphere->xyz) + right->w;
+ if (distToCenter < -sphere->w) {
+ return false;
+ }
+ distToCenter = dot(top->xyz, sphere->xyz) + top->w;
+ if (distToCenter < -sphere->w) {
+ return false;
+ }
+ distToCenter = dot(bottom->xyz, sphere->xyz) + bottom->w;
+ if (distToCenter < -sphere->w) {
+ return false;
+ }
+ distToCenter = dot(near->xyz, sphere->xyz) + near->w;
+ if (distToCenter < -sphere->w) {
+ return false;
+ }
+ distToCenter = dot(far->xyz, sphere->xyz) + far->w;
+ if (distToCenter < -sphere->w) {
+ return false;
+ }
+ return true;
+}
+
+
/**
- * Atomic Set the value at addr to the min of addr and value
- * addr[0] = rsMin(addr[0], value)
+ * Pack floating point (0-1) RGB values into a uchar4. The alpha component is
+ * set to 255 (1.0).
*
- * @param addr Address of value to modify
- * @param value comparison value
+ * @param r
+ * @param g
+ * @param b
*
- * @return old value
+ * @return uchar4
*/
-extern int32_t __attribute__((overloadable))
- rsAtomicMin(volatile int32_t* addr, int32_t value);
+_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b);
/**
- * Atomic Set the value at addr to the max of addr and value
- * addr[0] = rsMax(addr[0], value)
+ * Pack floating point (0-1) RGBA values into a uchar4.
*
- * @param addr Address of value to modify
- * @param value comparison value
+ * @param r
+ * @param g
+ * @param b
+ * @param a
*
- * @return old value
+ * @return uchar4
*/
-extern uint32_t __attribute__((overloadable))
- rsAtomicMax(volatile uint32_t* addr, uint32_t value);
+_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float r, float g, float b, float a);
+
/**
- * Atomic Set the value at addr to the max of addr and value
- * addr[0] = rsMin(addr[0], value)
+ * Pack floating point (0-1) RGB values into a uchar4. The alpha component is
+ * set to 255 (1.0).
*
- * @param addr Address of value to modify
- * @param value comparison value
+ * @param color
*
- * @return old value
+ * @return uchar4
*/
-extern int32_t __attribute__((overloadable))
- rsAtomicMax(volatile int32_t* addr, int32_t value);
+_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float3 color);
/**
- * Compare-and-set operation with a full memory barrier.
- *
- * If the value at addr matches compareValue then newValue is written.
+ * Pack floating point (0-1) RGBA values into a uchar4.
*
- * @param addr The address to compare and replace if the compare passes.
- * @param compareValue The value to test addr[0] against.
- * @param newValue The value to write if the test passes.
+ * @param color
*
- * @return old value
+ * @return uchar4
*/
-extern int32_t __attribute__((overloadable))
- rsAtomicCas(volatile int32_t* addr, int32_t compareValue, int32_t newValue);
+_RS_RUNTIME uchar4 __attribute__((overloadable)) rsPackColorTo8888(float4 color);
/**
- * Compare-and-set operation with a full memory barrier.
- *
- * If the value at addr matches compareValue then newValue is written.
+ * Unpack a uchar4 color to float4. The resulting float range will be (0-1).
*
- * @param addr The address to compare and replace if the compare passes.
- * @param compareValue The value to test addr[0] against.
- * @param newValue The value to write if the test passes.
+ * @param c
*
- * @return old value
+ * @return float4
*/
-extern uint32_t __attribute__((overloadable))
- rsAtomicCas(volatile uint32_t* addr, int32_t compareValue, int32_t newValue);
+_RS_RUNTIME float4 rsUnpackColor8888(uchar4 c);
#endif
diff --git a/libs/rs/scriptc/rs_matrix.rsh b/libs/rs/scriptc/rs_matrix.rsh
new file mode 100644
index 000000000000..ab3cd3b25a6e
--- /dev/null
+++ b/libs/rs/scriptc/rs_matrix.rsh
@@ -0,0 +1,378 @@
+/*
+ * 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.
+ */
+
+/** @file rs_matrix.rsh
+ * \brief Matrix routines
+ *
+ *
+ */
+
+#ifndef __RS_MATRIX_RSH__
+#define __RS_MATRIX_RSH__
+
+/**
+ * Set one element of a matrix.
+ *
+ * @param m The matrix to be set
+ * @param row
+ * @param col
+ * @param v
+ *
+ * @return void
+ */
+_RS_RUNTIME void __attribute__((overloadable))
+rsMatrixSet(rs_matrix4x4 *m, uint32_t row, uint32_t col, float v);
+/**
+ * \overload
+ */
+_RS_RUNTIME void __attribute__((overloadable))
+rsMatrixSet(rs_matrix3x3 *m, uint32_t row, uint32_t col, float v);
+/**
+ * \overload
+ */
+_RS_RUNTIME void __attribute__((overloadable))
+rsMatrixSet(rs_matrix2x2 *m, uint32_t row, uint32_t col, float v);
+
+/**
+ * Get one element of a matrix.
+ *
+ * @param m The matrix to read from
+ * @param row
+ * @param col
+ *
+ * @return float
+ */
+_RS_RUNTIME float __attribute__((overloadable))
+rsMatrixGet(const rs_matrix4x4 *m, uint32_t row, uint32_t col);
+/**
+ * \overload
+ */
+_RS_RUNTIME float __attribute__((overloadable))
+rsMatrixGet(const rs_matrix3x3 *m, uint32_t row, uint32_t col);
+/**
+ * \overload
+ */
+_RS_RUNTIME float __attribute__((overloadable))
+rsMatrixGet(const rs_matrix2x2 *m, uint32_t row, uint32_t col);
+
+/**
+ * Set the elements of a matrix to the identity matrix.
+ *
+ * @param m
+ */
+extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix4x4 *m);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix3x3 *m);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoadIdentity(rs_matrix2x2 *m);
+
+/**
+ * Set the elements of a matrix from an array of floats.
+ *
+ * @param m
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const float *v);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const float *v);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const float *v);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix4x4 *v);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix3x3 *v);
+
+/**
+ * Set the elements of a matrix from another matrix.
+ *
+ * @param m
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix4x4 *m, const rs_matrix2x2 *v);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix3x3 *m, const rs_matrix3x3 *v);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixLoad(rs_matrix2x2 *m, const rs_matrix2x2 *v);
+
+/**
+ * Load a rotation matrix.
+ *
+ * @param m
+ * @param rot
+ * @param x
+ * @param y
+ * @param z
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
+
+/**
+ * Load a scale matrix.
+ *
+ * @param m
+ * @param x
+ * @param y
+ * @param z
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadScale(rs_matrix4x4 *m, float x, float y, float z);
+
+/**
+ * Load a translation matrix.
+ *
+ * @param m
+ * @param x
+ * @param y
+ * @param z
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadTranslate(rs_matrix4x4 *m, float x, float y, float z);
+
+/**
+ * Multiply two matrix (lhs, rhs) and place the result in m.
+ *
+ * @param m
+ * @param lhs
+ * @param rhs
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *lhs, const rs_matrix4x4 *rhs);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *lhs, const rs_matrix3x3 *rhs);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *lhs, const rs_matrix2x2 *rhs);
+
+/**
+ * Multiply the matrix m by rhs and place the result back into m.
+ *
+ * @param m (lhs)
+ * @param rhs
+ */
+extern void __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix4x4 *m, const rs_matrix4x4 *rhs);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix3x3 *m, const rs_matrix3x3 *rhs);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix2x2 *m, const rs_matrix2x2 *rhs);
+
+/**
+ * Multiple matrix m with a rotation matrix
+ *
+ * @param m
+ * @param rot
+ * @param x
+ * @param y
+ * @param z
+ */
+extern void __attribute__((overloadable))
+rsMatrixRotate(rs_matrix4x4 *m, float rot, float x, float y, float z);
+
+/**
+ * Multiple matrix m with a scale matrix
+ *
+ * @param m
+ * @param x
+ * @param y
+ * @param z
+ */
+extern void __attribute__((overloadable))
+rsMatrixScale(rs_matrix4x4 *m, float x, float y, float z);
+
+/**
+ * Multiple matrix m with a translation matrix
+ *
+ * @param m
+ * @param x
+ * @param y
+ * @param z
+ */
+extern void __attribute__((overloadable))
+rsMatrixTranslate(rs_matrix4x4 *m, float x, float y, float z);
+
+/**
+ * Load an Ortho projection matrix constructed from the 6 planes
+ *
+ * @param m
+ * @param left
+ * @param right
+ * @param bottom
+ * @param top
+ * @param near
+ * @param far
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadOrtho(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
+
+/**
+ * Load an Frustum projection matrix constructed from the 6 planes
+ *
+ * @param m
+ * @param left
+ * @param right
+ * @param bottom
+ * @param top
+ * @param near
+ * @param far
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadFrustum(rs_matrix4x4 *m, float left, float right, float bottom, float top, float near, float far);
+
+/**
+ * Load an perspective projection matrix constructed from the 6 planes
+ *
+ * @param m
+ * @param fovy Field of view, in degrees along the Y axis.
+ * @param aspect Ratio of x / y.
+ * @param near
+ * @param far
+ */
+extern void __attribute__((overloadable))
+rsMatrixLoadPerspective(rs_matrix4x4* m, float fovy, float aspect, float near, float far);
+
+#if !defined(RS_VERSION) || (RS_VERSION < 14)
+/**
+ * Multiply a vector by a matrix and return the result vector.
+ * API version 10-13
+ */
+_RS_RUNTIME float4 __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix4x4 *m, float4 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float4 __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix4x4 *m, float3 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float4 __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix4x4 *m, float2 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float3 __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix3x3 *m, float3 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float3 __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix3x3 *m, float2 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float2 __attribute__((overloadable))
+rsMatrixMultiply(rs_matrix2x2 *m, float2 in);
+#else
+/**
+ * Multiply a vector by a matrix and return the result vector.
+ * API version 10-13
+ */
+_RS_RUNTIME float4 __attribute__((overloadable))
+rsMatrixMultiply(const rs_matrix4x4 *m, float4 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float4 __attribute__((overloadable))
+rsMatrixMultiply(const rs_matrix4x4 *m, float3 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float4 __attribute__((overloadable))
+rsMatrixMultiply(const rs_matrix4x4 *m, float2 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float3 __attribute__((overloadable))
+rsMatrixMultiply(const rs_matrix3x3 *m, float3 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float3 __attribute__((overloadable))
+rsMatrixMultiply(const rs_matrix3x3 *m, float2 in);
+
+/**
+ * \overload
+ */
+_RS_RUNTIME float2 __attribute__((overloadable))
+rsMatrixMultiply(const rs_matrix2x2 *m, float2 in);
+#endif
+
+
+/**
+ * Returns true if the matrix was successfully inversed
+ *
+ * @param m
+ */
+extern bool __attribute__((overloadable)) rsMatrixInverse(rs_matrix4x4 *m);
+
+/**
+ * Returns true if the matrix was successfully inversed and transposed.
+ *
+ * @param m
+ */
+extern bool __attribute__((overloadable)) rsMatrixInverseTranspose(rs_matrix4x4 *m);
+
+/**
+ * Transpose the matrix m.
+ *
+ * @param m
+ */
+extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix4x4 *m);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix3x3 *m);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable)) rsMatrixTranspose(rs_matrix2x2 *m);
+
+
+#endif
diff --git a/libs/rs/scriptc/rs_object.rsh b/libs/rs/scriptc/rs_object.rsh
new file mode 100644
index 000000000000..a43121937ea8
--- /dev/null
+++ b/libs/rs/scriptc/rs_object.rsh
@@ -0,0 +1,205 @@
+/*
+ * 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.
+ */
+
+/** @file rs_object.rsh
+ * \brief Object routines
+ *
+ *
+ */
+
+#ifndef __RS_OBJECT_RSH__
+#define __RS_OBJECT_RSH__
+
+
+/**
+ * Copy reference to the specified object.
+ *
+ * @param dst
+ * @param src
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_element *dst, rs_element src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_type *dst, rs_type src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_allocation *dst, rs_allocation src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_sampler *dst, rs_sampler src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_script *dst, rs_script src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_mesh *dst, rs_mesh src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_program_fragment *dst, rs_program_fragment src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_program_vertex *dst, rs_program_vertex src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_program_raster *dst, rs_program_raster src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_program_store *dst, rs_program_store src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsSetObject(rs_font *dst, rs_font src);
+
+/**
+ * Sets the object to NULL.
+ *
+ * @return bool
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_element *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_type *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_allocation *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_sampler *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_script *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_mesh *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_program_fragment *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_program_vertex *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_program_raster *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_program_store *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
+ rsClearObject(rs_font *dst);
+
+
+
+/**
+ * Tests if the object is valid. Returns true if the object is valid, false if
+ * it is NULL.
+ *
+ * @return bool
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_element);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_type);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_allocation);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_sampler);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_script);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_mesh);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_program_fragment);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_program_vertex);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_program_raster);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_program_store);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
+ rsIsObject(rs_font);
+
+#endif
diff --git a/libs/rs/scriptc/rs_quaternion.rsh b/libs/rs/scriptc/rs_quaternion.rsh
new file mode 100644
index 000000000000..36e6736c6c6f
--- /dev/null
+++ b/libs/rs/scriptc/rs_quaternion.rsh
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+
+/** @file rs_matrix.rsh
+ * \brief Quaternion routines
+ *
+ *
+ */
+
+#ifndef __RS_QUATERNION_RSH__
+#define __RS_QUATERNION_RSH__
+
+
+/**
+ * Set the quaternion components
+ * @param w component
+ * @param x component
+ * @param y component
+ * @param z component
+ */
+static void __attribute__((overloadable))
+rsQuaternionSet(rs_quaternion *q, float w, float x, float y, float z) {
+ q->w = w;
+ q->x = x;
+ q->y = y;
+ q->z = z;
+}
+
+/**
+ * Set the quaternion from another quaternion
+ * @param q destination quaternion
+ * @param rhs source quaternion
+ */
+static void __attribute__((overloadable))
+rsQuaternionSet(rs_quaternion *q, const rs_quaternion *rhs) {
+ q->w = rhs->w;
+ q->x = rhs->x;
+ q->y = rhs->y;
+ q->z = rhs->z;
+}
+
+/**
+ * Multiply quaternion by a scalar
+ * @param q quaternion to multiply
+ * @param s scalar
+ */
+static void __attribute__((overloadable))
+rsQuaternionMultiply(rs_quaternion *q, float s) {
+ q->w *= s;
+ q->x *= s;
+ q->y *= s;
+ q->z *= s;
+}
+
+/**
+ * Multiply quaternion by another quaternion
+ * @param q destination quaternion
+ * @param rhs right hand side quaternion to multiply by
+ */
+static void __attribute__((overloadable))
+rsQuaternionMultiply(rs_quaternion *q, const rs_quaternion *rhs) {
+ q->w = -q->x*rhs->x - q->y*rhs->y - q->z*rhs->z + q->w*rhs->w;
+ q->x = q->x*rhs->w + q->y*rhs->z - q->z*rhs->y + q->w*rhs->x;
+ q->y = -q->x*rhs->z + q->y*rhs->w + q->z*rhs->x + q->w*rhs->y;
+ q->z = q->x*rhs->y - q->y*rhs->x + q->z*rhs->w + q->w*rhs->z;
+}
+
+/**
+ * Add two quaternions
+ * @param q destination quaternion to add to
+ * @param rsh right hand side quaternion to add
+ */
+static void
+rsQuaternionAdd(rs_quaternion *q, const rs_quaternion *rhs) {
+ q->w *= rhs->w;
+ q->x *= rhs->x;
+ q->y *= rhs->y;
+ q->z *= rhs->z;
+}
+
+/**
+ * Loads a quaternion that represents a rotation about an arbitrary unit vector
+ * @param q quaternion to set
+ * @param rot angle to rotate by
+ * @param x component of a vector
+ * @param y component of a vector
+ * @param x component of a vector
+ */
+static void
+rsQuaternionLoadRotateUnit(rs_quaternion *q, float rot, float x, float y, float z) {
+ rot *= (float)(M_PI / 180.0f) * 0.5f;
+ float c = cos(rot);
+ float s = sin(rot);
+
+ q->w = c;
+ q->x = x * s;
+ q->y = y * s;
+ q->z = z * s;
+}
+
+/**
+ * Loads a quaternion that represents a rotation about an arbitrary vector
+ * (doesn't have to be unit)
+ * @param q quaternion to set
+ * @param rot angle to rotate by
+ * @param x component of a vector
+ * @param y component of a vector
+ * @param x component of a vector
+ */
+static void
+rsQuaternionLoadRotate(rs_quaternion *q, float rot, float x, float y, float z) {
+ const float len = x*x + y*y + z*z;
+ if (len != 1) {
+ const float recipLen = 1.f / sqrt(len);
+ x *= recipLen;
+ y *= recipLen;
+ z *= recipLen;
+ }
+ rsQuaternionLoadRotateUnit(q, rot, x, y, z);
+}
+
+/**
+ * Conjugates the quaternion
+ * @param q quaternion to conjugate
+ */
+static void
+rsQuaternionConjugate(rs_quaternion *q) {
+ q->x = -q->x;
+ q->y = -q->y;
+ q->z = -q->z;
+}
+
+/**
+ * Dot product of two quaternions
+ * @param q0 first quaternion
+ * @param q1 second quaternion
+ * @return dot product between q0 and q1
+ */
+static float
+rsQuaternionDot(const rs_quaternion *q0, const rs_quaternion *q1) {
+ return q0->w*q1->w + q0->x*q1->x + q0->y*q1->y + q0->z*q1->z;
+}
+
+/**
+ * Normalizes the quaternion
+ * @param q quaternion to normalize
+ */
+static void
+rsQuaternionNormalize(rs_quaternion *q) {
+ const float len = rsQuaternionDot(q, q);
+ if (len != 1) {
+ const float recipLen = 1.f / sqrt(len);
+ rsQuaternionMultiply(q, recipLen);
+ }
+}
+
+/**
+ * Performs spherical linear interpolation between two quaternions
+ * @param q result quaternion from interpolation
+ * @param q0 first param
+ * @param q1 second param
+ * @param t how much to interpolate by
+ */
+static void
+rsQuaternionSlerp(rs_quaternion *q, const rs_quaternion *q0, const rs_quaternion *q1, float t) {
+ if (t <= 0.0f) {
+ rsQuaternionSet(q, q0);
+ return;
+ }
+ if (t >= 1.0f) {
+ rsQuaternionSet(q, q1);
+ return;
+ }
+
+ rs_quaternion tempq0, tempq1;
+ rsQuaternionSet(&tempq0, q0);
+ rsQuaternionSet(&tempq1, q1);
+
+ float angle = rsQuaternionDot(q0, q1);
+ if (angle < 0) {
+ rsQuaternionMultiply(&tempq0, -1.0f);
+ angle *= -1.0f;
+ }
+
+ float scale, invScale;
+ if (angle + 1.0f > 0.05f) {
+ if (1.0f - angle >= 0.05f) {
+ float theta = acos(angle);
+ float invSinTheta = 1.0f / sin(theta);
+ scale = sin(theta * (1.0f - t)) * invSinTheta;
+ invScale = sin(theta * t) * invSinTheta;
+ } else {
+ scale = 1.0f - t;
+ invScale = t;
+ }
+ } else {
+ rsQuaternionSet(&tempq1, tempq0.z, -tempq0.y, tempq0.x, -tempq0.w);
+ scale = sin(M_PI * (0.5f - t));
+ invScale = sin(M_PI * t);
+ }
+
+ rsQuaternionSet(q, tempq0.w*scale + tempq1.w*invScale, tempq0.x*scale + tempq1.x*invScale,
+ tempq0.y*scale + tempq1.y*invScale, tempq0.z*scale + tempq1.z*invScale);
+}
+
+/**
+ * Computes rotation matrix from the normalized quaternion
+ * @param m resulting matrix
+ * @param p normalized quaternion
+ */
+static void rsQuaternionGetMatrixUnit(rs_matrix4x4 *m, const rs_quaternion *q) {
+ float x2 = 2.0f * q->x * q->x;
+ float y2 = 2.0f * q->y * q->y;
+ float z2 = 2.0f * q->z * q->z;
+ float xy = 2.0f * q->x * q->y;
+ float wz = 2.0f * q->w * q->z;
+ float xz = 2.0f * q->x * q->z;
+ float wy = 2.0f * q->w * q->y;
+ float wx = 2.0f * q->w * q->x;
+ float yz = 2.0f * q->y * q->z;
+
+ m->m[0] = 1.0f - y2 - z2;
+ m->m[1] = xy - wz;
+ m->m[2] = xz + wy;
+ m->m[3] = 0.0f;
+
+ m->m[4] = xy + wz;
+ m->m[5] = 1.0f - x2 - z2;
+ m->m[6] = yz - wx;
+ m->m[7] = 0.0f;
+
+ m->m[8] = xz - wy;
+ m->m[9] = yz - wx;
+ m->m[10] = 1.0f - x2 - y2;
+ m->m[11] = 0.0f;
+
+ m->m[12] = 0.0f;
+ m->m[13] = 0.0f;
+ m->m[14] = 0.0f;
+ m->m[15] = 1.0f;
+}
+
+#endif
+
diff --git a/libs/rs/scriptc/rs_time.rsh b/libs/rs/scriptc/rs_time.rsh
index f1abed6308e4..f8f297d32a18 100644
--- a/libs/rs/scriptc/rs_time.rsh
+++ b/libs/rs/scriptc/rs_time.rsh
@@ -1,3 +1,25 @@
+/*
+ * 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.
+ */
+
+/** @file rs_time.rsh
+ * \brief Time routines
+ *
+ *
+ */
+
#ifndef __RS_TIME_RSH__
#define __RS_TIME_RSH__
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 121e013cf0ee..875beb9b196d 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -1,98 +1,377 @@
+/*
+ * 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.
+ */
+
+/** @file rs_types.rsh
+ *
+ * Define the standard Renderscript types
+ *
+ * Integers
+ * 8 bit: char, int8_t
+ * 16 bit: short, int16_t
+ * 32 bit: int, in32_t
+ * 64 bit: long, long long, int64_t
+ *
+ * Unsigned Integers
+ * 8 bit: uchar, uint8_t
+ * 16 bit: ushort, uint16_t
+ * 32 bit: uint, uint32_t
+ * 64 bit: ulong, uint64_t
+ *
+ * Floating point
+ * 32 bit: float
+ * 64 bit: double
+ *
+ * Vectors of length 2, 3, and 4 are supported for all the types above.
+ *
+ */
+
#ifndef __RS_TYPES_RSH__
#define __RS_TYPES_RSH__
#define M_PI 3.14159265358979323846264338327950288f /* pi */
#include "stdbool.h"
+/**
+ * 8 bit integer type
+ */
typedef char int8_t;
+/**
+ * 16 bit integer type
+ */
typedef short int16_t;
+/**
+ * 32 bit integer type
+ */
typedef int int32_t;
+/**
+ * 64 bit integer type
+ */
typedef long long int64_t;
-
+/**
+ * 8 bit unsigned integer type
+ */
typedef unsigned char uint8_t;
+/**
+ * 16 bit unsigned integer type
+ */
typedef unsigned short uint16_t;
+/**
+ * 32 bit unsigned integer type
+ */
typedef unsigned int uint32_t;
+/**
+ * 64 bit unsigned integer type
+ */
typedef unsigned long long uint64_t;
-
+/**
+ * 8 bit unsigned integer type
+ */
typedef uint8_t uchar;
+/**
+ * 16 bit unsigned integer type
+ */
typedef uint16_t ushort;
+/**
+ * 32 bit unsigned integer type
+ */
typedef uint32_t uint;
+/**
+ * Typedef for unsigned char (use for 64-bit unsigned integers)
+ */
typedef uint64_t ulong;
-
+/**
+ * Typedef for unsigned int
+ */
typedef uint32_t size_t;
+/**
+ * Typedef for int (use for 32-bit integers)
+ */
typedef int32_t ssize_t;
+/**
+ * \brief Opaque handle to a RenderScript element.
+ *
+ * See: android.renderscript.Element
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_element;
+/**
+ * \brief Opaque handle to a RenderScript type.
+ *
+ * See: android.renderscript.Type
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_type;
+/**
+ * \brief Opaque handle to a RenderScript allocation.
+ *
+ * See: android.renderscript.Allocation
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_allocation;
+/**
+ * \brief Opaque handle to a RenderScript sampler object.
+ *
+ * See: android.renderscript.Sampler
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_sampler;
+/**
+ * \brief Opaque handle to a RenderScript script object.
+ *
+ * See: android.renderscript.ScriptC
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_script;
+/**
+ * \brief Opaque handle to a RenderScript mesh object.
+ *
+ * See: android.renderscript.Mesh
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_mesh;
+/**
+ * \brief Opaque handle to a RenderScript ProgramFragment object.
+ *
+ * See: android.renderscript.ProgramFragment
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_program_fragment;
+/**
+ * \brief Opaque handle to a RenderScript ProgramVertex object.
+ *
+ * See: android.renderscript.ProgramVertex
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_program_vertex;
+/**
+ * \brief Opaque handle to a RenderScript sampler object.
+ *
+ * See: android.renderscript.Sampler
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_program_raster;
+/**
+ * \brief Opaque handle to a RenderScript ProgramStore object.
+ *
+ * See: android.renderscript.ProgramStore
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_program_store;
+/**
+ * \brief Opaque handle to a RenderScript font object.
+ *
+ * See: android.renderscript.Font
+ */
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_font;
-
+/**
+ * Vector version of the basic float type.
+ * Provides two float fields packed into a single 64bit field with 64 bit
+ * alignment.
+ */
typedef float float2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic float type. Provides three float fields packed
+ * into a single 128bit field with 128 bit alignment.
+ */
typedef float float3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic float type.
+ * Provides four float fields packed into a single 128bit field with 128bit
+ * alignment.
+ */
typedef float float4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic double type. Provides two double fields packed
+ * into a single 128bit field with 128bit alignment.
+ */
typedef double double2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic double type. Provides three double fields packed
+ * into a single 256bit field with 256bit alignment.
+ */
typedef double double3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic double type. Provides four double fields packed
+ * into a single 256bit field with 256bit alignment.
+ */
typedef double double4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic uchar type. Provides two uchar fields packed
+ * into a single 16bit field with 16bit alignment.
+ */
typedef uchar uchar2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic uchar type. Provides three uchar fields packed
+ * into a single 32bit field with 32bit alignment.
+ */
typedef uchar uchar3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic uchar type. Provides four uchar fields packed
+ * into a single 32bit field with 32bit alignment.
+ */
typedef uchar uchar4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic ushort type. Provides two ushort fields packed
+ * into a single 32bit field with 32bit alignment.
+ */
typedef ushort ushort2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic ushort type. Provides three ushort fields packed
+ * into a single 64bit field with 64bit alignment.
+ */
typedef ushort ushort3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic ushort type. Provides four ushort fields packed
+ * into a single 64bit field with 64bit alignment.
+ */
typedef ushort ushort4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic uint type. Provides two uint fields packed into a
+ * single 64bit field with 64bit alignment.
+ */
typedef uint uint2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic uint type. Provides three uint fields packed into
+ * a single 128bit field with 128bit alignment.
+ */
typedef uint uint3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic uint type. Provides four uint fields packed into
+ * a single 128bit field with 128bit alignment.
+ */
typedef uint uint4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic ulong type. Provides two ulong fields packed into
+ * a single 128bit field with 128bit alignment.
+ */
typedef ulong ulong2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic ulong type. Provides three ulong fields packed
+ * into a single 256bit field with 256bit alignment.
+ */
typedef ulong ulong3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic ulong type. Provides four ulong fields packed
+ * into a single 256bit field with 256bit alignment.
+ */
typedef ulong ulong4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic char type. Provides two char fields packed into a
+ * single 16bit field with 16bit alignment.
+ */
typedef char char2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic char type. Provides three char fields packed into
+ * a single 32bit field with 32bit alignment.
+ */
typedef char char3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic char type. Provides four char fields packed into
+ * a single 32bit field with 32bit alignment.
+ */
typedef char char4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic short type. Provides two short fields packed into
+ * a single 32bit field with 32bit alignment.
+ */
typedef short short2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic short type. Provides three short fields packed
+ * into a single 64bit field with 64bit alignment.
+ */
typedef short short3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic short type. Provides four short fields packed
+ * into a single 64bit field with 64bit alignment.
+ */
typedef short short4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic int type. Provides two int fields packed into a
+ * single 64bit field with 64bit alignment.
+ */
typedef int int2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic int type. Provides three int fields packed into a
+ * single 128bit field with 128bit alignment.
+ */
typedef int int3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic int type. Provides two four fields packed into a
+ * single 128bit field with 128bit alignment.
+ */
typedef int int4 __attribute__((ext_vector_type(4)));
+/**
+ * Vector version of the basic long type. Provides two long fields packed into a
+ * single 128bit field with 128bit alignment.
+ */
typedef long long2 __attribute__((ext_vector_type(2)));
+/**
+ * Vector version of the basic long type. Provides three long fields packed into
+ * a single 256bit field with 256bit alignment.
+ */
typedef long long3 __attribute__((ext_vector_type(3)));
+/**
+ * Vector version of the basic long type. Provides four long fields packed into
+ * a single 256bit field with 256bit alignment.
+ */
typedef long long4 __attribute__((ext_vector_type(4)));
+/**
+ * \brief 4x4 float matrix
+ *
+ * Native holder for RS matrix. Elements are stored in the array at the
+ * location [row*4 + col]
+ */
typedef struct {
float m[16];
} rs_matrix4x4;
-
+/**
+ * \brief 3x3 float matrix
+ *
+ * Native holder for RS matrix. Elements are stored in the array at the
+ * location [row*3 + col]
+ */
typedef struct {
float m[9];
} rs_matrix3x3;
-
+/**
+ * \brief 2x2 float matrix
+ *
+ * Native holder for RS matrix. Elements are stored in the array at the
+ * location [row*2 + col]
+ */
typedef struct {
float m[4];
} rs_matrix2x2;
+/**
+ * quaternion type for use with the quaternion functions
+ */
typedef float4 rs_quaternion;
#define RS_PACKED __attribute__((packed, aligned(4)))
-
#define NULL ((const void *)0)
+
+/**
+ * \brief Enum for selecting cube map faces
+ *
+ * Used todo-alexst
+ */
typedef enum {
RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X = 0,
RS_ALLOCATION_CUBEMAP_FACE_NEGATIVE_X = 1,
@@ -102,6 +381,12 @@ typedef enum {
RS_ALLOCATION_CUBEMAP_FACE_NEGATIVE_Z = 5
} rs_allocation_cubemap_face;
+/**
+ * \brief Bitfield to specify the usage types for an allocation.
+ *
+ * These values are ORed together to specify which usages or memory spaces are
+ * relevant to an allocation or an operation on an allocation.
+ */
typedef enum {
RS_ALLOCATION_USAGE_SCRIPT = 0x0001,
RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE = 0x0002,
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 020646b9c416..f24a71d88d9d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -24,8 +24,6 @@
#include <EGL/egl.h>
-#include <system/graphics.h>
-
#include <private/ui/android_natives_priv.h>
// ----------------------------------------------------------------------------
@@ -69,49 +67,31 @@ status_t EGLUtils::selectConfigForPixelFormat(
return BAD_VALUE;
// Get all the "potential match" configs...
- if (eglChooseConfig(dpy, attrs, 0, 0, &numConfigs) == EGL_FALSE)
+ if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
- if (numConfigs) {
- EGLConfig* const configs = new EGLConfig[numConfigs];
- if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) {
- delete [] configs;
- return BAD_VALUE;
- }
-
- bool hasAlpha = false;
- switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_RGBA_5551:
- case HAL_PIXEL_FORMAT_RGBA_4444:
- hasAlpha = true;
- break;
- }
-
- // The first config is guaranteed to over-satisfy the constraints
- EGLConfig config = configs[0];
-
- // go through the list and skip configs that over-satisfy our needs
- int i;
- for (i=0 ; i<n ; i++) {
- if (!hasAlpha) {
- EGLint alphaSize;
- eglGetConfigAttrib(dpy, configs[i], EGL_ALPHA_SIZE, &alphaSize);
- if (alphaSize > 0) {
- continue;
- }
- }
+ EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs);
+ if (eglChooseConfig(dpy, attrs, configs, numConfigs, &n) == EGL_FALSE) {
+ free(configs);
+ return BAD_VALUE;
+ }
+
+ int i;
+ EGLConfig config = NULL;
+ for (i=0 ; i<n ; i++) {
+ EGLint nativeVisualId = 0;
+ eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ if (nativeVisualId>0 && format == nativeVisualId) {
config = configs[i];
break;
}
+ }
- delete [] configs;
-
- if (i<n) {
- *outConfig = config;
- return NO_ERROR;
- }
+ free(configs);
+
+ if (i<n) {
+ *outConfig = config;
+ return NO_ERROR;
}
return NAME_NOT_FOUND;
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 0e8ae619fc5c..89497302a25f 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -317,6 +317,8 @@ int FramebufferNativeWindow::perform(ANativeWindow* window,
case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+ case NATIVE_WINDOW_API_CONNECT:
+ case NATIVE_WINDOW_API_DISCONNECT:
// TODO: we should implement these
return NO_ERROR;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 33ef1fc8945c..e75415b37b0b 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -61,13 +61,19 @@ void GraphicBufferAllocator::dump(String8& result) const
const size_t c = list.size();
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
- list.keyAt(i), rec.size/1024.0f,
- rec.w, rec.s, rec.h, rec.format, rec.usage);
+ if (rec.size) {
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
+ list.keyAt(i), rec.size/1024.0f,
+ rec.w, rec.s, rec.h, rec.format, rec.usage);
+ } else {
+ snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n",
+ list.keyAt(i),
+ rec.w, rec.s, rec.h, rec.format, rec.usage);
+ }
result.append(buffer);
total += rec.size;
}
- snprintf(buffer, SIZE, "Total allocated: %.2f KB\n", total/1024.0f);
+ snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
result.append(buffer);
if (mAllocDev->common.version >= 1 && mAllocDev->dump) {
mAllocDev->dump(mAllocDev, buffer, SIZE);
@@ -101,13 +107,19 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma
if (err == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+ int bpp = bytesPerPixel(format);
+ if (bpp < 0) {
+ // probably a HAL custom format. in any case, we don't know
+ // what its pixel size is.
+ bpp = 0;
+ }
alloc_rec_t rec;
rec.w = w;
rec.h = h;
rec.s = *stride;
rec.format = format;
rec.usage = usage;
- rec.size = h * stride[0] * bytesPerPixel(format);
+ rec.size = h * stride[0] * bpp;
list.add(*handle, rec);
}
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
index 0af7f8043c35..688b99892bf9 100644
--- a/libs/ui/Input.cpp
+++ b/libs/ui/Input.cpp
@@ -280,6 +280,9 @@ status_t PointerCoords::setAxisValue(int32_t axis, float value) {
uint64_t axisBit = 1LL << axis;
uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
if (!(bits & axisBit)) {
+ if (value == 0) {
+ return OK; // axes with value 0 do not need to be stored
+ }
uint32_t count = __builtin_popcountll(bits);
if (count >= MAX_AXES) {
tooManyAxes(axis);
@@ -294,23 +297,10 @@ status_t PointerCoords::setAxisValue(int32_t axis, float value) {
return OK;
}
-float* PointerCoords::editAxisValue(int32_t axis) {
- if (axis < 0 || axis > 63) {
- return NULL;
- }
-
- uint64_t axisBit = 1LL << axis;
- if (!(bits & axisBit)) {
- return NULL;
- }
- uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
- return &values[index];
-}
-
static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
- float* value = c.editAxisValue(axis);
- if (value) {
- *value *= scaleFactor;
+ float value = c.getAxisValue(axis);
+ if (value != 0) {
+ c.setAxisValue(axis, value * scaleFactor);
}
}
@@ -574,20 +564,14 @@ void MotionEvent::transform(const SkMatrix* matrix) {
size_t numSamples = mSamplePointerCoords.size();
for (size_t i = 0; i < numSamples; i++) {
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
- float* xPtr = c.editAxisValue(AMOTION_EVENT_AXIS_X);
- float* yPtr = c.editAxisValue(AMOTION_EVENT_AXIS_Y);
- if (xPtr && yPtr) {
- float x = *xPtr + oldXOffset;
- float y = *yPtr + oldYOffset;
- matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
- *xPtr = SkScalarToFloat(point.fX) - newXOffset;
- *yPtr = SkScalarToFloat(point.fY) - newYOffset;
- }
+ float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
+ float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
+ matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
+ c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
+ c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
- float* orientationPtr = c.editAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
- if (orientationPtr) {
- *orientationPtr = transformAngle(matrix, *orientationPtr);
- }
+ float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
+ c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
}
}
@@ -727,7 +711,7 @@ void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Posi
}
while (idBits.count() > MAX_POINTERS) {
- idBits.clearBit(idBits.lastMarkedBit());
+ idBits.clearLastMarkedBit();
}
Movement& movement = mMovements[mIndex];
@@ -776,7 +760,7 @@ void VelocityTracker::addMovement(const MotionEvent* event) {
// 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());
+ downIdBits.markBit(event->getPointerId(event->getActionIndex()));
clearPointers(downIdBits);
break;
}
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/ui/tests/InputEvent_test.cpp
index e48d5b7dc53c..e21c464a1974 100644
--- a/libs/ui/tests/InputEvent_test.cpp
+++ b/libs/ui/tests/InputEvent_test.cpp
@@ -52,9 +52,6 @@ TEST_F(PointerCoordsTest, AxisValues) {
ASSERT_EQ(0, coords.getAxisValue(1))
<< "getAxisValue should return zero because axis is not present";
- ASSERT_EQ(NULL, coords.editAxisValue(0))
- << "editAxisValue should return null because axis is not present";
-
// Set first axis.
ASSERT_EQ(OK, coords.setAxisValue(1, 5));
ASSERT_EQ(0x00000002ULL, coords.bits);
@@ -96,26 +93,17 @@ TEST_F(PointerCoordsTest, AxisValues) {
ASSERT_EQ(2, coords.getAxisValue(3))
<< "getAxisValue should return value of axis";
- // Edit an existing axis value in place.
- valuePtr = coords.editAxisValue(1);
- ASSERT_EQ(5, *valuePtr)
- << "editAxisValue should return pointer to axis value";
-
- *valuePtr = 7;
- ASSERT_EQ(7, coords.getAxisValue(1))
- << "getAxisValue should return value of axis";
-
// Set an axis with an id between the others. (inserting value in the middle)
ASSERT_EQ(OK, coords.setAxisValue(2, 1));
ASSERT_EQ(0x0000000fULL, coords.bits);
ASSERT_EQ(4, coords.values[0]);
- ASSERT_EQ(7, coords.values[1]);
+ ASSERT_EQ(5, coords.values[1]);
ASSERT_EQ(1, coords.values[2]);
ASSERT_EQ(2, coords.values[3]);
ASSERT_EQ(4, coords.getAxisValue(0))
<< "getAxisValue should return value of axis";
- ASSERT_EQ(7, coords.getAxisValue(1))
+ ASSERT_EQ(5, coords.getAxisValue(1))
<< "getAxisValue should return value of axis";
ASSERT_EQ(1, coords.getAxisValue(2))
<< "getAxisValue should return value of axis";
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index 8db2009587f7..37d061cb3cbb 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -49,11 +49,6 @@ namespace android {
// ---------------------------------------------------------------------------
-RefBase::Destroyer::~Destroyer() {
-}
-
-// ---------------------------------------------------------------------------
-
class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
@@ -61,7 +56,6 @@ public:
volatile int32_t mWeak;
RefBase* const mBase;
volatile int32_t mFlags;
- Destroyer* mDestroyer;
#if !DEBUG_REFS
@@ -70,7 +64,6 @@ public:
, mWeak(0)
, mBase(base)
, mFlags(0)
- , mDestroyer(0)
{
}
@@ -113,7 +106,7 @@ public:
LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
#if DEBUG_REFS_CALLSTACK_ENABLED
refs->stack.dump();
-#endif;
+#endif
refs = refs->next;
}
}
@@ -131,7 +124,7 @@ public:
LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
#if DEBUG_REFS_CALLSTACK_ENABLED
refs->stack.dump();
-#endif;
+#endif
refs = refs->next;
}
}
@@ -193,7 +186,7 @@ public:
String8 text;
{
- Mutex::Autolock _l(const_cast<weakref_impl*>(this)->mMutex);
+ Mutex::Autolock _l(mMutex);
char buf[128];
sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
text.append(buf);
@@ -318,7 +311,7 @@ private:
}
}
- Mutex mMutex;
+ mutable Mutex mMutex;
ref_entry* mStrongRefs;
ref_entry* mWeakRefs;
@@ -348,7 +341,7 @@ void RefBase::incStrong(const void* id) const
}
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
- const_cast<RefBase*>(this)->onFirstRef();
+ refs->mBase->onFirstRef();
}
void RefBase::decStrong(const void* id) const
@@ -361,13 +354,9 @@ void RefBase::decStrong(const void* id) const
#endif
LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs);
if (c == 1) {
- const_cast<RefBase*>(this)->onLastStrongRef(id);
- if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
- if (refs->mDestroyer) {
- refs->mDestroyer->destroy(this);
- } else {
- delete this;
- }
+ refs->mBase->onLastStrongRef(id);
+ if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) {
+ delete this;
}
}
refs->decWeak(id);
@@ -391,7 +380,7 @@ void RefBase::forceIncStrong(const void* id) const
android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong);
// fall through...
case 0:
- const_cast<RefBase*>(this)->onFirstRef();
+ refs->mBase->onFirstRef();
}
}
@@ -400,10 +389,6 @@ int32_t RefBase::getStrongCount() const
return mRefs->mStrong;
}
-void RefBase::setDestroyer(RefBase::Destroyer* destroyer) {
- mRefs->mDestroyer = destroyer;
-}
-
RefBase* RefBase::weakref_type::refBase() const
{
return static_cast<const weakref_impl*>(this)->mBase;
@@ -417,6 +402,7 @@ void RefBase::weakref_type::incWeak(const void* id)
LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);
}
+
void RefBase::weakref_type::decWeak(const void* id)
{
weakref_impl* const impl = static_cast<weakref_impl*>(this);
@@ -424,30 +410,27 @@ void RefBase::weakref_type::decWeak(const void* id)
const int32_t c = android_atomic_dec(&impl->mWeak);
LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this);
if (c != 1) return;
-
- if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) {
+
+ if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) {
+ // This is the regular lifetime case. The object is destroyed
+ // when the last strong reference goes away. Since weakref_impl
+ // outlive the object, it is not destroyed in the dtor, and
+ // we'll have to do it here.
if (impl->mStrong == INITIAL_STRONG_VALUE) {
- if (impl->mBase) {
- if (impl->mDestroyer) {
- impl->mDestroyer->destroy(impl->mBase);
- } else {
- delete impl->mBase;
- }
- }
+ // Special case: we never had a strong reference, so we need to
+ // destroy the object now.
+ delete impl->mBase;
} else {
// LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
+ // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER}
impl->mBase->onLastWeakRef(id);
- if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) {
- if (impl->mBase) {
- if (impl->mDestroyer) {
- impl->mDestroyer->destroy(impl->mBase);
- } else {
- delete impl->mBase;
- }
- }
+ if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) {
+ // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference
+ // is gone, we can destroy the object.
+ delete impl->mBase;
}
}
}
@@ -569,11 +552,23 @@ RefBase::RefBase()
RefBase::~RefBase()
{
- if ((mRefs->mFlags & OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK) {
- if (mRefs->mWeak == 0) {
- delete mRefs;
+ if (mRefs->mStrong == INITIAL_STRONG_VALUE) {
+ // we never acquired a strong (and/or weak) reference on this object.
+ delete mRefs;
+ } else {
+ // life-time of this object is extended to WEAK or FOREVER, in
+ // which case weakref_impl doesn't out-live the object and we
+ // can free it now.
+ if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) {
+ // It's possible that the weak count is not 0 if the object
+ // re-acquired a weak reference in its destructor
+ if (mRefs->mWeak == 0) {
+ delete mRefs;
+ }
}
}
+ // for debugging purposes, clear this.
+ const_cast<weakref_impl*&>(mRefs) = NULL;
}
void RefBase::extendObjectLifetime(int32_t mode)