diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/cpustats/Android.mk | 21 | ||||
| -rw-r--r-- | libs/cpustats/CentralTendencyStatistics.cpp | 81 | ||||
| -rw-r--r-- | libs/cpustats/ThreadCpuUsage.cpp | 252 | ||||
| -rw-r--r-- | libs/hwui/DisplayListRenderer.cpp | 81 | ||||
| -rw-r--r-- | libs/hwui/DisplayListRenderer.h | 10 | ||||
| -rw-r--r-- | libs/hwui/FontRenderer.cpp | 4 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 23 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 4 | ||||
| -rw-r--r-- | libs/rs/driver/rsdGL.cpp | 8 | ||||
| -rw-r--r-- | libs/rs/driver/rsdProgram.cpp | 12 | ||||
| -rw-r--r-- | libs/rs/driver/rsdShader.cpp | 88 | ||||
| -rw-r--r-- | libs/rs/driver/rsdShader.h | 28 | ||||
| -rw-r--r-- | libs/rs/driver/rsdShaderCache.cpp | 66 | ||||
| -rw-r--r-- | libs/rs/driver/rsdShaderCache.h | 4 |
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(); |
