summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/cpustats/Android.mk21
-rw-r--r--libs/cpustats/CentralTendencyStatistics.cpp81
-rw-r--r--libs/cpustats/ThreadCpuUsage.cpp252
-rw-r--r--libs/hwui/DisplayListRenderer.cpp81
-rw-r--r--libs/hwui/DisplayListRenderer.h10
-rw-r--r--libs/hwui/FontRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp23
-rw-r--r--libs/hwui/OpenGLRenderer.h4
-rw-r--r--libs/rs/driver/rsdGL.cpp8
-rw-r--r--libs/rs/driver/rsdProgram.cpp12
-rw-r--r--libs/rs/driver/rsdShader.cpp88
-rw-r--r--libs/rs/driver/rsdShader.h28
-rw-r--r--libs/rs/driver/rsdShaderCache.cpp66
-rw-r--r--libs/rs/driver/rsdShaderCache.h4
14 files changed, 179 insertions, 503 deletions
diff --git a/libs/cpustats/Android.mk b/libs/cpustats/Android.mk
deleted file mode 100644
index 21bacbb..0000000
--- a/libs/cpustats/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- CentralTendencyStatistics.cpp \
- ThreadCpuUsage.cpp
-
-LOCAL_MODULE := libcpustats
-
-include $(BUILD_STATIC_LIBRARY)
-
-#include $(CLEAR_VARS)
-#
-#LOCAL_SRC_FILES := \
-# CentralTendencyStatistics.cpp \
-# ThreadCpuUsage.cpp
-#
-#LOCAL_MODULE := libcpustats
-#
-#include $(BUILD_HOST_STATIC_LIBRARY)
diff --git a/libs/cpustats/CentralTendencyStatistics.cpp b/libs/cpustats/CentralTendencyStatistics.cpp
deleted file mode 100644
index 42ab62b..0000000
--- a/libs/cpustats/CentralTendencyStatistics.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-
-#include <cpustats/CentralTendencyStatistics.h>
-
-void CentralTendencyStatistics::sample(double x)
-{
- // update min and max
- if (x < mMinimum)
- mMinimum = x;
- if (x > mMaximum)
- mMaximum = x;
- // Knuth
- if (mN == 0) {
- mMean = 0;
- }
- ++mN;
- double delta = x - mMean;
- mMean += delta / mN;
- mM2 += delta * (x - mMean);
-}
-
-void CentralTendencyStatistics::reset()
-{
- mMean = NAN;
- mMedian = NAN;
- mMinimum = INFINITY;
- mMaximum = -INFINITY;
- mN = 0;
- mM2 = 0;
- mVariance = NAN;
- mVarianceKnownForN = 0;
- mStddev = NAN;
- mStddevKnownForN = 0;
-}
-
-double CentralTendencyStatistics::variance() const
-{
- double variance;
- if (mVarianceKnownForN != mN) {
- if (mN > 1) {
- // double variance_n = M2/n;
- variance = mM2 / (mN - 1);
- } else {
- variance = NAN;
- }
- mVariance = variance;
- mVarianceKnownForN = mN;
- } else {
- variance = mVariance;
- }
- return variance;
-}
-
-double CentralTendencyStatistics::stddev() const
-{
- double stddev;
- if (mStddevKnownForN != mN) {
- stddev = sqrt(variance());
- mStddev = stddev;
- mStddevKnownForN = mN;
- } else {
- stddev = mStddev;
- }
- return stddev;
-}
diff --git a/libs/cpustats/ThreadCpuUsage.cpp b/libs/cpustats/ThreadCpuUsage.cpp
deleted file mode 100644
index 99b4c83..0000000
--- a/libs/cpustats/ThreadCpuUsage.cpp
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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.
- */
-
-#define LOG_TAG "ThreadCpuUsage"
-//#define LOG_NDEBUG 0
-
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-
-#include <cpustats/ThreadCpuUsage.h>
-
-namespace android {
-
-bool ThreadCpuUsage::setEnabled(bool isEnabled)
-{
- bool wasEnabled = mIsEnabled;
- // only do something if there is a change
- if (isEnabled != wasEnabled) {
- ALOGV("setEnabled(%d)", isEnabled);
- int rc;
- // enabling
- if (isEnabled) {
- rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mPreviousTs);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_THREAD_CPUTIME_ID) errno=%d", errno);
- isEnabled = false;
- } else {
- mWasEverEnabled = true;
- // record wall clock time at first enable
- if (!mMonotonicKnown) {
- rc = clock_gettime(CLOCK_MONOTONIC, &mMonotonicTs);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_MONOTONIC) errno=%d", errno);
- } else {
- mMonotonicKnown = true;
- }
- }
- }
- // disabling
- } else {
- struct timespec ts;
- rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_THREAD_CPUTIME_ID) errno=%d", errno);
- } else {
- long long delta = (ts.tv_sec - mPreviousTs.tv_sec) * 1000000000LL +
- (ts.tv_nsec - mPreviousTs.tv_nsec);
- mAccumulator += delta;
-#if 0
- mPreviousTs = ts;
-#endif
- }
- }
- mIsEnabled = isEnabled;
- }
- return wasEnabled;
-}
-
-bool ThreadCpuUsage::sampleAndEnable(double& ns)
-{
- bool ret;
- bool wasEverEnabled = mWasEverEnabled;
- if (enable()) {
- // already enabled, so add a new sample relative to previous
- return sample(ns);
- } else if (wasEverEnabled) {
- // was disabled, but add sample for accumulated time while enabled
- ns = (double) mAccumulator;
- mAccumulator = 0;
- ALOGV("sampleAndEnable %.0f", ns);
- return true;
- } else {
- // first time called
- ns = 0.0;
- ALOGV("sampleAndEnable false");
- return false;
- }
-}
-
-bool ThreadCpuUsage::sample(double &ns)
-{
- if (mWasEverEnabled) {
- if (mIsEnabled) {
- struct timespec ts;
- int rc;
- rc = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_THREAD_CPUTIME_ID) errno=%d", errno);
- ns = 0.0;
- return false;
- } else {
- long long delta = (ts.tv_sec - mPreviousTs.tv_sec) * 1000000000LL +
- (ts.tv_nsec - mPreviousTs.tv_nsec);
- mAccumulator += delta;
- mPreviousTs = ts;
- }
- } else {
- mWasEverEnabled = false;
- }
- ns = (double) mAccumulator;
- ALOGV("sample %.0f", ns);
- mAccumulator = 0;
- return true;
- } else {
- ALOGW("Can't add sample because measurements have never been enabled");
- ns = 0.0;
- return false;
- }
-}
-
-long long ThreadCpuUsage::elapsed() const
-{
- long long elapsed;
- if (mMonotonicKnown) {
- struct timespec ts;
- int rc;
- rc = clock_gettime(CLOCK_MONOTONIC, &ts);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_MONOTONIC) errno=%d", errno);
- elapsed = 0;
- } else {
- // mMonotonicTs is updated only at first enable and resetStatistics
- elapsed = (ts.tv_sec - mMonotonicTs.tv_sec) * 1000000000LL +
- (ts.tv_nsec - mMonotonicTs.tv_nsec);
- }
- } else {
- ALOGW("Can't compute elapsed time because measurements have never been enabled");
- elapsed = 0;
- }
- ALOGV("elapsed %lld", elapsed);
- return elapsed;
-}
-
-void ThreadCpuUsage::resetElapsed()
-{
- ALOGV("resetElapsed");
- if (mMonotonicKnown) {
- int rc;
- rc = clock_gettime(CLOCK_MONOTONIC, &mMonotonicTs);
- if (rc) {
- ALOGE("clock_gettime(CLOCK_MONOTONIC) errno=%d", errno);
- mMonotonicKnown = false;
- }
- }
-}
-
-/*static*/
-int ThreadCpuUsage::sScalingFds[ThreadCpuUsage::MAX_CPU];
-pthread_once_t ThreadCpuUsage::sOnceControl = PTHREAD_ONCE_INIT;
-int ThreadCpuUsage::sKernelMax;
-
-/*static*/
-void ThreadCpuUsage::init()
-{
- // read the number of CPUs
- sKernelMax = 1;
- int fd = open("/sys/devices/system/cpu/kernel_max", O_RDONLY);
- if (fd >= 0) {
-#define KERNEL_MAX_SIZE 12
- char kernelMax[KERNEL_MAX_SIZE];
- ssize_t actual = read(fd, kernelMax, sizeof(kernelMax));
- if (actual >= 2 && kernelMax[actual-1] == '\n') {
- sKernelMax = atoi(kernelMax);
- if (sKernelMax >= MAX_CPU - 1) {
- ALOGW("kernel_max %d but MAX_CPU %d", sKernelMax, MAX_CPU);
- sKernelMax = MAX_CPU;
- } else if (sKernelMax < 0) {
- ALOGW("kernel_max invalid %d", sKernelMax);
- sKernelMax = 1;
- } else {
- ++sKernelMax;
- ALOGV("number of CPUs %d", sKernelMax);
- }
- } else {
- ALOGW("Can't read number of CPUs");
- }
- (void) close(fd);
- } else {
- ALOGW("Can't open number of CPUs");
- }
-
- // open fd to each frequency per CPU
-#define FREQ_SIZE 64
- char freq_path[FREQ_SIZE];
-#define FREQ_DIGIT 27
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10);
- strlcpy(freq_path, "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq", sizeof(freq_path));
- int i;
- for (i = 0; i < MAX_CPU; ++i) {
- sScalingFds[i] = -1;
- }
- for (i = 0; i < sKernelMax; ++i) {
- freq_path[FREQ_DIGIT] = i + '0';
- fd = open(freq_path, O_RDONLY);
- if (fd >= 0) {
- // keep this fd until process exit
- sScalingFds[i] = fd;
- } else {
- ALOGW("Can't open CPU %d", i);
- }
- }
-}
-
-uint32_t ThreadCpuUsage::getCpukHz(int cpuNum)
-{
- if (cpuNum < 0 || cpuNum >= MAX_CPU) {
- ALOGW("getCpukHz called with invalid CPU %d", cpuNum);
- return 0;
- }
- int fd = sScalingFds[cpuNum];
- if (fd < 0) {
- ALOGW("getCpukHz called for unopened CPU %d", cpuNum);
- return 0;
- }
-#define KHZ_SIZE 12
- char kHz[KHZ_SIZE]; // kHz base 10
- ssize_t actual = pread(fd, kHz, sizeof(kHz), (off_t) 0);
- uint32_t ret;
- if (actual >= 2 && kHz[actual-1] == '\n') {
- ret = atoi(kHz);
- } else {
- ret = 0;
- }
- if (ret != mCurrentkHz[cpuNum]) {
- if (ret > 0) {
- ALOGV("CPU %d frequency %u kHz", cpuNum, ret);
- } else {
- ALOGW("Can't read CPU %d frequency", cpuNum);
- }
- mCurrentkHz[cpuNum] = ret;
- }
- return ret;
-}
-
-} // namespace android
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 118608d..3a3f8a5 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -18,6 +18,8 @@
#include <SkCamera.h>
+#include <private/hwui/DrawGlInfo.h>
+
#include "DisplayListLogBuffer.h"
#include "DisplayListRenderer.h"
#include "Caches.h"
@@ -104,7 +106,7 @@ DisplayList::~DisplayList() {
void DisplayList::initProperties() {
mLeft = 0;
mTop = 0;
- mTop = 0;
+ mRight = 0;
mBottom = 0;
mApplicationScale = -1;
mClipChildren = true;
@@ -119,6 +121,7 @@ void DisplayList::initProperties() {
mScaleY = 1;
mPivotX = 0;
mPivotY = 0;
+ mCameraDistance = 0;
mMatrixDirty = false;
mMatrixFlags = 0;
mPrevWidth = -1;
@@ -684,7 +687,7 @@ void DisplayList::outputViewProperties(OpenGLRenderer& renderer, char* indent) {
mTransformMatrix->get(8));
}
}
- if (mAlpha < 1) {
+ if (mAlpha < 1 && !mCaching) {
// TODO: should be able to store the size of a DL at record time and not
// have to pass it into this call. In fact, this information might be in the
// location/size info that we store with the new native transform data.
@@ -763,42 +766,14 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t width, ui
}
}
-void DisplayList::transformRect(float left, float top, float right, float bottom, Rect& result) {
- result.left = left + mLeft;
- result.top = top + mTop;
- result.right = right + mLeft;
- result.bottom = bottom + mTop;
- if (mMatrixFlags != 0) {
- if (mMatrixFlags == TRANSLATION) {
- result.left += mTranslationX;
- result.top += mTranslationY;
- result.right += mTranslationX;
- result.bottom += mTranslationY;
- } else {
- updateMatrix();
- SkRect r;
- r.fLeft = result.left;
- r.fTop = result.top;
- r.fRight = result.right;
- r.fBottom = result.bottom;
- mTransformMatrix->mapRect(&r);
- result.left = r.fLeft;
- result.top = r.fTop;
- result.right = r.fRight;
- result.bottom = r.fBottom;
- }
- }
-}
-
-
/**
* Changes to replay(), specifically those involving opcode or parameter changes, should be mimicked
* in the output() function, since that function processes the same list of opcodes for the
* purposes of logging display list info for a given view.
*/
-bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
+status_t DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
- bool needsInvalidate = false;
+ status_t drawGlStatus = 0;
TextContainer text;
mReader.rewind();
@@ -820,6 +795,12 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
}
setViewProperties(renderer, width, height, level);
+ if (USE_DISPLAY_LIST_PROPERTIES && renderer.quickReject(0, 0, width, height)) {
+ DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, "RestoreToCount", restoreTo);
+ renderer.restoreToCount(restoreTo);
+ renderer.endMark();
+ return false;
+ }
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
int saveCount = renderer.getSaveCount() - 1;
@@ -843,7 +824,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
Functor *functor = (Functor *) getInt();
DISPLAY_LIST_LOGD("%s%s %p", (char*) indent, OP_NAMES[op], functor);
renderer.startMark("GL functor");
- needsInvalidate |= renderer.callDrawGLFunction(functor, dirty);
+ drawGlStatus |= renderer.callDrawGLFunction(functor, dirty);
renderer.endMark();
}
break;
@@ -950,7 +931,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
displayList, width, height, flags, level + 1);
- needsInvalidate |= renderer.drawDisplayList(displayList, width,
+ drawGlStatus |= renderer.drawDisplayList(displayList, width,
height, dirty, flags, level + 1);
}
break;
@@ -972,6 +953,9 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
+ if (mCaching && mMultipliedAlpha < 255) {
+ paint->setAlpha(mMultipliedAlpha);
+ }
DISPLAY_LIST_LOGD("%s%s %p, %.2f, %.2f, %p", (char*) indent, OP_NAMES[op],
bitmap, x, y, paint);
renderer.drawBitmap(bitmap, x, y, paint);
@@ -1233,8 +1217,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, uint32_t width,
renderer.endMark();
DISPLAY_LIST_LOGD("%sDone (%p, %s), returning %d", (char*) indent + 2, this, mName.string(),
- needsInvalidate);
- return needsInvalidate;
+ drawGlStatus);
+ return drawGlStatus;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1321,11 +1305,11 @@ void DisplayListRenderer::interrupt() {
void DisplayListRenderer::resume() {
}
-bool DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
+status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
// Ignore dirty during recording, it matters only when we replay
addOp(DisplayList::DrawGLFunction);
addInt((int) functor);
- return false; // No invalidate needed at record-time
+ return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
}
int DisplayListRenderer::save(int flags) {
@@ -1415,29 +1399,16 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
}
-bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
+status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
uint32_t width, uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
- float top = 0;
- float left = 0;
- float right = width;
- float bottom = height;
- if (USE_DISPLAY_LIST_PROPERTIES) {
- Rect transformedRect;
- displayList->transformRect(left, top, right, bottom, transformedRect);
- left = transformedRect.left;
- top = transformedRect.top;
- right = transformedRect.right;
- bottom = transformedRect.bottom;
- }
- const bool reject = quickReject(left, top, right, bottom);
- uint32_t* location = addOp(DisplayList::DrawDisplayList, reject);
+
+ addOp(DisplayList::DrawDisplayList);
addDisplayList(displayList);
addSize(width, height);
addInt(flags);
- addSkip(location);
- return false;
+ return DrawGlInfo::kStatusDone;
}
void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 4bbb04f..4a9886b 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -51,7 +51,7 @@ namespace uirenderer {
// Set to 1 to enable native processing of View properties. 0 by default. Eventually this
// will go away and we will always use this approach for accelerated apps.
-#define USE_DISPLAY_LIST_PROPERTIES 0
+#define USE_DISPLAY_LIST_PROPERTIES 1
#define TRANSLATION 0x0001
#define ROTATION 0x0002
@@ -137,7 +137,7 @@ public:
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
- bool replay(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
+ status_t replay(OpenGLRenderer& renderer, uint32_t width, uint32_t height,
Rect& dirty, int32_t flags, uint32_t level = 0);
void output(OpenGLRenderer& renderer, uint32_t level = 0);
@@ -379,8 +379,6 @@ public:
mCaching = caching;
}
- void transformRect(float left, float top, float right, float bottom, Rect& result);
-
private:
void init();
@@ -525,7 +523,7 @@ public:
virtual void prepareDirty(float left, float top, float right, float bottom, bool opaque);
virtual void finish();
- virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
+ virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);
virtual void interrupt();
virtual void resume();
@@ -549,7 +547,7 @@ public:
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+ virtual status_t drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
Rect& dirty, int32_t flags, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index d7937c7..9e7fbb5 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -518,6 +518,8 @@ FontRenderer::~FontRenderer() {
mCacheLines.clear();
if (mInitialized) {
+ // Unbinding the buffer shouldn't be necessary but it crashes with some drivers
+ Caches::getInstance().unbindIndicesBuffer();
glDeleteBuffers(1, &mIndexBufferID);
delete[] mTextMeshPtr;
@@ -777,7 +779,7 @@ void FontRenderer::checkInit() {
// We store a string with letters in a rough frequency of occurrence
mLatinPrecache = String16("eisarntolcdugpmhbyfvkwzxjq ");
mLatinPrecache += String16("EISARNTOLCDUGPMHBYFVKWZXJQ");
- mLatinPrecache += String16(",.?!()-+@;:`'");
+ mLatinPrecache += String16(",.?!()-+@;:'");
mLatinPrecache += String16("0123456789");
mInitialized = true;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 685fddc..eb4b83b 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -236,7 +236,7 @@ void OpenGLRenderer::resume() {
glBlendEquation(GL_FUNC_ADD);
}
-bool OpenGLRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
+status_t OpenGLRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
interrupt();
if (mDirtyClip) {
setScissorFromClip();
@@ -269,7 +269,7 @@ bool OpenGLRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
}
resume();
- return result != 0;
+ return result;
}
///////////////////////////////////////////////////////////////////////////////
@@ -1321,21 +1321,10 @@ void OpenGLRenderer::finishDrawTexture() {
// Drawing
///////////////////////////////////////////////////////////////////////////////
-bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
Rect& dirty, int32_t flags, uint32_t level) {
- float top = 0;
- float left = 0;
- float right = width;
- float bottom = height;
- if (USE_DISPLAY_LIST_PROPERTIES) {
- Rect transformedRect;
- displayList->transformRect(left, top, right, bottom, transformedRect);
- left = transformedRect.left;
- top = transformedRect.top;
- right = transformedRect.right;
- bottom = transformedRect.bottom;
- }
- if (quickReject(left, top, right, bottom)) {
+
+ if (!USE_DISPLAY_LIST_PROPERTIES && quickReject(0, 0, width, height)) {
return false;
}
@@ -1345,7 +1334,7 @@ bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, u
return displayList->replay(*this, width, height, dirty, flags, level);
}
- return false;
+ return DrawGlInfo::kStatusDone;
}
void OpenGLRenderer::outputDisplayList(DisplayList* displayList, uint32_t level) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 4d7a491..3ba6202 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -72,7 +72,7 @@ public:
virtual void interrupt();
virtual void resume();
- virtual bool callDrawGLFunction(Functor *functor, Rect& dirty);
+ virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);
ANDROID_API int getSaveCount() const;
virtual int save(int flags);
@@ -97,7 +97,7 @@ public:
ANDROID_API bool quickReject(float left, float top, float right, float bottom);
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
- virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
+ virtual status_t drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
Rect& dirty, int32_t flags, uint32_t level = 0);
virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index fae602c..0860417 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -43,6 +43,7 @@
#include "rsdFrameBufferObj.h"
#include <gui/SurfaceTextureClient.h>
+#include <gui/DummyConsumer.h>
using namespace android;
using namespace android::renderscript;
@@ -326,8 +327,11 @@ bool rsdGLInit(const Context *rsc) {
}
gGLContextCount++;
- sp<SurfaceTexture> st(new SurfaceTexture(123));
- sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st));
+ // Create a BufferQueue with a fake consumer
+ sp<BufferQueue> bq = new BufferQueue();
+ sp<DummyConsumer> dummy = new DummyConsumer(bq);
+ sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(bq)));
+
dc->gl.egl.surfaceDefault = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
static_cast<ANativeWindow*>(stc.get()),
NULL);
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
index 30a4c5f..a96a5f9 100644
--- a/libs/rs/driver/rsdProgram.cpp
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -71,10 +71,10 @@ void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) {
if(pv->mHal.drv) {
drv = (RsdShader*)pv->mHal.drv;
if (rsc->props.mLogShaders) {
- ALOGV("Destroying vertex shader with ID %u", drv->getShaderID());
+ ALOGV("Destroying vertex shader with ID %u", (uint32_t)pv);
}
- if (drv->getShaderID()) {
- dc->gl.shaderCache->cleanupVertex(drv->getShaderID());
+ if (drv->getStateBasedIDCount()) {
+ dc->gl.shaderCache->cleanupVertex(drv);
}
delete drv;
}
@@ -105,10 +105,10 @@ void rsdProgramFragmentDestroy(const Context *rsc, const ProgramFragment *pf) {
if(pf->mHal.drv) {
drv = (RsdShader*)pf->mHal.drv;
if (rsc->props.mLogShaders) {
- ALOGV("Destroying fragment shader with ID %u", drv->getShaderID());
+ ALOGV("Destroying fragment shader with ID %u", (uint32_t)pf);
}
- if (drv->getShaderID()) {
- dc->gl.shaderCache->cleanupFragment(drv->getShaderID());
+ if (drv->getStateBasedIDCount()) {
+ dc->gl.shaderCache->cleanupFragment(drv);
}
delete drv;
}
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index a386735..6d9fa90 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -46,30 +46,74 @@ RsdShader::RsdShader(const Program *p, uint32_t type,
}
RsdShader::~RsdShader() {
- if (mShaderID) {
- glDeleteShader(mShaderID);
+ for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) {
+ StateBasedKey *state = mStateBasedShaders.itemAt(i);
+ if (state->mShaderID) {
+ glDeleteShader(state->mShaderID);
+ }
+ delete state;
}
delete[] mAttribNames;
delete[] mUniformNames;
delete[] mUniformArraySizes;
- delete[] mTextureTargets;
}
void RsdShader::initMemberVars() {
mDirty = true;
- mShaderID = 0;
mAttribCount = 0;
mUniformCount = 0;
mAttribNames = NULL;
mUniformNames = NULL;
mUniformArraySizes = NULL;
- mTextureTargets = NULL;
+ mCurrentState = NULL;
mIsValid = false;
}
+RsdShader::StateBasedKey *RsdShader::getExistingState() {
+ RsdShader::StateBasedKey *returnKey = NULL;
+
+ for (uint32_t i = 0; i < mStateBasedShaders.size(); i ++) {
+ returnKey = mStateBasedShaders.itemAt(i);
+
+ for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) {
+ uint32_t texType = 0;
+ if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
+ Allocation *a = mRSProgram->mHal.state.textures[ct];
+ if (a && a->mHal.state.surfaceTextureID) {
+ texType = GL_TEXTURE_EXTERNAL_OES;
+ } else {
+ texType = GL_TEXTURE_2D;
+ }
+ } else {
+ texType = GL_TEXTURE_CUBE_MAP;
+ }
+ if (texType != returnKey->mTextureTargets[ct]) {
+ returnKey = NULL;
+ break;
+ }
+ }
+ }
+ return returnKey;
+}
+
+uint32_t RsdShader::getStateBasedShaderID(const Context *rsc) {
+ StateBasedKey *state = getExistingState();
+ if (state != NULL) {
+ mCurrentState = state;
+ return mCurrentState->mShaderID;
+ }
+ // We have not created a shader for this particular state yet
+ state = new StateBasedKey(mTextureCount);
+ mCurrentState = state;
+ mStateBasedShaders.add(state);
+ createShader();
+ loadShader(rsc);
+ return mCurrentState->mShaderID;
+}
+
void RsdShader::init(const char** textureNames, size_t textureNamesCount,
const size_t *textureNamesLength) {
uint32_t attribCount = 0;
@@ -155,14 +199,14 @@ void RsdShader::appendTextures() {
appendUsing = false;
}
mShader.append("uniform samplerExternalOES UNI_");
- mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
+ mCurrentState->mTextureTargets[ct] = GL_TEXTURE_EXTERNAL_OES;
} else {
mShader.append("uniform sampler2D UNI_");
- mTextureTargets[ct] = GL_TEXTURE_2D;
+ mCurrentState->mTextureTargets[ct] = GL_TEXTURE_2D;
}
} else {
mShader.append("uniform samplerCube UNI_");
- mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
+ mCurrentState->mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP;
}
mShader.append(mTextureNames[ct]);
@@ -171,6 +215,7 @@ void RsdShader::appendTextures() {
}
bool RsdShader::createShader() {
+ mShader.clear();
if (mType == GL_FRAGMENT_SHADER) {
mShader.append("precision mediump float;\n");
}
@@ -183,37 +228,37 @@ bool RsdShader::createShader() {
}
bool RsdShader::loadShader(const Context *rsc) {
- mShaderID = glCreateShader(mType);
- rsAssert(mShaderID);
+ mCurrentState->mShaderID = glCreateShader(mType);
+ rsAssert(mCurrentState->mShaderID);
if(!mShader.length()) {
createShader();
}
if (rsc->props.mLogShaders) {
- ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
+ ALOGV("Loading shader type %x, ID %i", mType, mCurrentState->mShaderID);
ALOGV("%s", mShader.string());
}
- if (mShaderID) {
+ if (mCurrentState->mShaderID) {
const char * ss = mShader.string();
- RSD_CALL_GL(glShaderSource, mShaderID, 1, &ss, NULL);
- RSD_CALL_GL(glCompileShader, mShaderID);
+ RSD_CALL_GL(glShaderSource, mCurrentState->mShaderID, 1, &ss, NULL);
+ RSD_CALL_GL(glCompileShader, mCurrentState->mShaderID);
GLint compiled = 0;
- RSD_CALL_GL(glGetShaderiv, mShaderID, GL_COMPILE_STATUS, &compiled);
+ RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint infoLen = 0;
- RSD_CALL_GL(glGetShaderiv, mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
+ RSD_CALL_GL(glGetShaderiv, mCurrentState->mShaderID, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen) {
char* buf = (char*) malloc(infoLen);
if (buf) {
- RSD_CALL_GL(glGetShaderInfoLog, mShaderID, infoLen, NULL, buf);
+ RSD_CALL_GL(glGetShaderInfoLog, mCurrentState->mShaderID, infoLen, NULL, buf);
rsc->setError(RS_ERROR_FATAL_PROGRAM_LINK, buf);
free(buf);
}
- RSD_CALL_GL(glDeleteShader, mShaderID);
- mShaderID = 0;
+ RSD_CALL_GL(glDeleteShader, mCurrentState->mShaderID);
+ mCurrentState->mShaderID = 0;
return false;
}
}
@@ -430,7 +475,7 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) {
if (!mRSProgram->mHal.state.textures[ct]) {
// if nothing is bound, reset to default GL texture
- RSD_CALL_GL(glBindTexture, mTextureTargets[ct], 0);
+ RSD_CALL_GL(glBindTexture, mCurrentState->mTextureTargets[ct], 0);
continue;
}
@@ -537,9 +582,6 @@ void RsdShader::initAttribAndUniformArray() {
}
mTextureCount = mRSProgram->mHal.state.texturesCount;
- if (mTextureCount) {
- mTextureTargets = new uint32_t[mTextureCount];
- }
}
void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths,
diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h
index 6c0b616..2680b3e 100644
--- a/libs/rs/driver/rsdShader.h
+++ b/libs/rs/driver/rsdShader.h
@@ -44,9 +44,13 @@ public:
const size_t *textureNamesLength);
virtual ~RsdShader();
- bool createShader();
+ uint32_t getStateBasedShaderID(const android::renderscript::Context *);
- uint32_t getShaderID() const {return mShaderID;}
+ // Add ability to get all ID's to clean up the cached program objects
+ uint32_t getStateBasedIDCount() const { return mStateBasedShaders.size(); }
+ uint32_t getStateBasedID(uint32_t index) const {
+ return mStateBasedShaders.itemAt(index)->mShaderID;
+ }
uint32_t getAttribCount() const {return mAttribCount;}
uint32_t getUniformCount() const {return mUniformCount;}
@@ -64,6 +68,21 @@ public:
protected:
+ class StateBasedKey {
+ public:
+ StateBasedKey(uint32_t texCount) : mShaderID(0) {
+ mTextureTargets = new uint32_t[texCount];
+ }
+ ~StateBasedKey() {
+ delete[] mTextureTargets;
+ }
+ uint32_t mShaderID;
+ uint32_t *mTextureTargets;
+ };
+
+ bool createShader();
+ StateBasedKey *getExistingState();
+
const android::renderscript::Program *mRSProgram;
bool mIsValid;
@@ -87,11 +106,10 @@ protected:
mutable bool mDirty;
android::String8 mShader;
android::String8 mUserShader;
- uint32_t mShaderID;
uint32_t mType;
uint32_t mTextureCount;
- uint32_t *mTextureTargets;
+ StateBasedKey *mCurrentState;
uint32_t mAttribCount;
uint32_t mUniformCount;
android::String8 *mAttribNames;
@@ -100,6 +118,8 @@ protected:
android::Vector<android::String8> mTextureNames;
+ android::Vector<StateBasedKey*> mStateBasedShaders;
+
int32_t mTextureUniformIndexStart;
void logUniform(const android::renderscript::Element *field,
diff --git a/libs/rs/driver/rsdShaderCache.cpp b/libs/rs/driver/rsdShaderCache.cpp
index 50cb9f9..69b43fc 100644
--- a/libs/rs/driver/rsdShaderCache.cpp
+++ b/libs/rs/driver/rsdShaderCache.cpp
@@ -108,21 +108,17 @@ bool RsdShaderCache::link(const Context *rsc) {
RsdShader *vtx = mVertex;
RsdShader *frag = mFragment;
- if (!vtx->getShaderID()) {
- vtx->loadShader(rsc);
- }
- if (!frag->getShaderID()) {
- frag->loadShader(rsc);
- }
+
+ uint32_t vID = vtx->getStateBasedShaderID(rsc);
+ uint32_t fID = frag->getStateBasedShaderID(rsc);
// Don't try to cache if shaders failed to load
- if (!vtx->getShaderID() || !frag->getShaderID()) {
+ if (!vID || !fID) {
return false;
}
uint32_t entryCount = mEntries.size();
for (uint32_t ct = 0; ct < entryCount; ct ++) {
- if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
- (mEntries[ct]->frag == frag->getShaderID())) {
+ if ((mEntries[ct]->vtx == vID) && (mEntries[ct]->frag == fID)) {
//ALOGV("SC using program %i", mEntries[ct]->program);
glUseProgram(mEntries[ct]->program);
@@ -138,14 +134,14 @@ bool RsdShaderCache::link(const Context *rsc) {
frag->getUniformCount());
mEntries.push(e);
mCurrent = e;
- e->vtx = vtx->getShaderID();
- e->frag = frag->getShaderID();
+ e->vtx = vID;
+ e->frag = fID;
e->program = glCreateProgram();
if (e->program) {
GLuint pgm = e->program;
- glAttachShader(pgm, vtx->getShaderID());
+ glAttachShader(pgm, vID);
//ALOGE("e1 %x", glGetError());
- glAttachShader(pgm, frag->getShaderID());
+ glAttachShader(pgm, fID);
glBindAttribLocation(pgm, 0, "ATTRIB_position");
glBindAttribLocation(pgm, 1, "ATTRIB_color");
@@ -241,30 +237,38 @@ int32_t RsdShaderCache::vtxAttribSlot(const String8 &attrName) const {
return -1;
}
-void RsdShaderCache::cleanupVertex(uint32_t id) {
+void RsdShaderCache::cleanupVertex(RsdShader *s) {
int32_t numEntries = (int32_t)mEntries.size();
- for (int32_t ct = 0; ct < numEntries; ct ++) {
- if (mEntries[ct]->vtx == id) {
- glDeleteProgram(mEntries[ct]->program);
-
- delete mEntries[ct];
- mEntries.removeAt(ct);
- numEntries = (int32_t)mEntries.size();
- ct --;
+ uint32_t numShaderIDs = s->getStateBasedIDCount();
+ for (uint32_t sId = 0; sId < numShaderIDs; sId ++) {
+ uint32_t id = s->getStateBasedID(sId);
+ for (int32_t ct = 0; ct < numEntries; ct ++) {
+ if (mEntries[ct]->vtx == id) {
+ glDeleteProgram(mEntries[ct]->program);
+
+ delete mEntries[ct];
+ mEntries.removeAt(ct);
+ numEntries = (int32_t)mEntries.size();
+ ct --;
+ }
}
}
}
-void RsdShaderCache::cleanupFragment(uint32_t id) {
+void RsdShaderCache::cleanupFragment(RsdShader *s) {
int32_t numEntries = (int32_t)mEntries.size();
- for (int32_t ct = 0; ct < numEntries; ct ++) {
- if (mEntries[ct]->frag == id) {
- glDeleteProgram(mEntries[ct]->program);
-
- delete mEntries[ct];
- mEntries.removeAt(ct);
- numEntries = (int32_t)mEntries.size();
- ct --;
+ uint32_t numShaderIDs = s->getStateBasedIDCount();
+ for (uint32_t sId = 0; sId < numShaderIDs; sId ++) {
+ uint32_t id = s->getStateBasedID(sId);
+ for (int32_t ct = 0; ct < numEntries; ct ++) {
+ if (mEntries[ct]->frag == id) {
+ glDeleteProgram(mEntries[ct]->program);
+
+ delete mEntries[ct];
+ mEntries.removeAt(ct);
+ numEntries = (int32_t)mEntries.size();
+ ct --;
+ }
}
}
}
diff --git a/libs/rs/driver/rsdShaderCache.h b/libs/rs/driver/rsdShaderCache.h
index 1192916..88aa32d 100644
--- a/libs/rs/driver/rsdShaderCache.h
+++ b/libs/rs/driver/rsdShaderCache.h
@@ -49,8 +49,8 @@ public:
bool setup(const android::renderscript::Context *rsc);
- void cleanupVertex(uint32_t id);
- void cleanupFragment(uint32_t id);
+ void cleanupVertex(RsdShader *s);
+ void cleanupFragment(RsdShader *s);
void cleanupAll();