diff options
Diffstat (limited to 'libs')
107 files changed, 5213 insertions, 831 deletions
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk new file mode 100644 index 0000000..c5f8a87 --- /dev/null +++ b/libs/androidfw/Android.mk @@ -0,0 +1,113 @@ +# Copyright (C) 2010 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH:= $(call my-dir) + +# libandroidfw is partially built for the host (used by build time keymap validation tool) +# These files are common to host and target builds. + +# formerly in libutils +commonUtilsSources:= \ + Asset.cpp \ + AssetDir.cpp \ + AssetManager.cpp \ + ObbFile.cpp \ + ResourceTypes.cpp \ + StreamingZipInflater.cpp \ + ZipFileCRO.cpp \ + ZipFileRO.cpp \ + ZipUtils.cpp + +# formerly in libui +commonUiSources:= \ + Input.cpp \ + Keyboard.cpp \ + KeyCharacterMap.cpp \ + KeyLayoutMap.cpp \ + VirtualKeyMap.cpp + +commonSources:= \ + $(commonUtilsSources) \ + $(commonUiSources) + +# For the host +# ===================================================== + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= $(commonSources) + +LOCAL_MODULE:= libandroidfw + +LOCAL_MODULE_TAGS := optional + +LOCAL_C_INCLUDES := \ + external/zlib + +include $(BUILD_HOST_STATIC_LIBRARY) + + +# For the device +# ===================================================== + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + $(commonSources) \ + BackupData.cpp \ + BackupHelpers.cpp \ + InputTransport.cpp + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libcutils \ + libutils \ + libbinder \ + libskia \ + libz + +LOCAL_C_INCLUDES := \ + external/skia/include/core \ + external/icu4c/common \ + external/zlib + +LOCAL_MODULE:= libandroidfw + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) + + +ifeq ($(TARGET_OS),linux) +include $(CLEAR_VARS) +LOCAL_C_INCLUDES += \ + external/skia/include/core \ + external/zlib \ + external/icu4c/common \ + bionic/libc/private +LOCAL_LDLIBS := -lrt -ldl -lpthread +LOCAL_MODULE := libandroidfw +LOCAL_SRC_FILES := $(commonUtilsSources) BackupData.cpp BackupHelpers.cpp +include $(BUILD_STATIC_LIBRARY) +endif + + +# Include subdirectory makefiles +# ============================================================ + +# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework +# team really wants is to build the stuff defined by this makefile. +ifeq (,$(ONE_SHOT_MAKEFILE)) +include $(call first-makefiles-under,$(LOCAL_PATH)) +endif diff --git a/libs/utils/Asset.cpp b/libs/androidfw/Asset.cpp index 50e701a..cb7628d 100644 --- a/libs/utils/Asset.cpp +++ b/libs/androidfw/Asset.cpp @@ -21,23 +21,23 @@ #define LOG_TAG "asset" //#define NDEBUG 0 -#include <utils/Asset.h> +#include <androidfw/Asset.h> +#include <androidfw/StreamingZipInflater.h> +#include <androidfw/ZipFileRO.h> +#include <androidfw/ZipUtils.h> #include <utils/Atomic.h> #include <utils/FileMap.h> -#include <utils/StreamingZipInflater.h> -#include <utils/ZipUtils.h> -#include <utils/ZipFileRO.h> #include <utils/Log.h> #include <utils/threads.h> -#include <string.h> -#include <memory.h> -#include <fcntl.h> -#include <errno.h> #include <assert.h> -#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <memory.h> +#include <string.h> #include <sys/stat.h> #include <sys/types.h> +#include <unistd.h> using namespace android; diff --git a/libs/utils/AssetDir.cpp b/libs/androidfw/AssetDir.cpp index c5f664e..475f521 100644 --- a/libs/utils/AssetDir.cpp +++ b/libs/androidfw/AssetDir.cpp @@ -19,7 +19,7 @@ // implementation is in the header file or in friend functions in // AssetManager. // -#include <utils/AssetDir.h> +#include <androidfw/AssetDir.h> using namespace android; diff --git a/libs/utils/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 47a2b99..4829add 100644 --- a/libs/utils/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -21,23 +21,23 @@ #define LOG_TAG "asset" //#define LOG_NDEBUG 0 -#include <utils/AssetManager.h> -#include <utils/AssetDir.h> -#include <utils/Asset.h> +#include <androidfw/Asset.h> +#include <androidfw/AssetDir.h> +#include <androidfw/AssetManager.h> +#include <androidfw/ResourceTypes.h> +#include <androidfw/ZipFileRO.h> #include <utils/Atomic.h> +#include <utils/Log.h> #include <utils/String8.h> -#include <utils/ResourceTypes.h> #include <utils/String8.h> -#include <utils/ZipFileRO.h> -#include <utils/Log.h> -#include <utils/Timers.h> #include <utils/threads.h> +#include <utils/Timers.h> +#include <assert.h> #include <dirent.h> #include <errno.h> -#include <assert.h> -#include <strings.h> #include <fcntl.h> +#include <strings.h> #include <sys/stat.h> #include <unistd.h> diff --git a/libs/utils/BackupData.cpp b/libs/androidfw/BackupData.cpp index f956306..7b1bcba 100644 --- a/libs/utils/BackupData.cpp +++ b/libs/androidfw/BackupData.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "backup_data" -#include <utils/BackupHelpers.h> +#include <androidfw/BackupHelpers.h> #include <utils/ByteOrder.h> #include <stdio.h> diff --git a/libs/utils/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp index f77a891..7a817a7 100644 --- a/libs/utils/BackupHelpers.cpp +++ b/libs/androidfw/BackupHelpers.cpp @@ -16,7 +16,7 @@ #define LOG_TAG "file_backup_helper" -#include <utils/BackupHelpers.h> +#include <androidfw/BackupHelpers.h> #include <utils/KeyedVector.h> #include <utils/ByteOrder.h> @@ -546,7 +546,7 @@ int write_tarfile(const String8& packageName, const String8& domain, // read/write up to this much at a time. const size_t BUFSIZE = 32 * 1024; - char* buf = new char[BUFSIZE]; + char* buf = (char *)calloc(1,BUFSIZE); char* paxHeader = buf + 512; // use a different chunk of it as separate scratch char* paxData = buf + 1024; @@ -556,9 +556,6 @@ int write_tarfile(const String8& packageName, const String8& domain, goto cleanup; } - // Good to go -- first construct the standard tar header at the start of the buffer - memset(buf, 0, BUFSIZE); - // Magic fields for the ustar file format strcat(buf + 257, "ustar"); strcat(buf + 263, "00"); diff --git a/libs/ui/Input.cpp b/libs/androidfw/Input.cpp index 263c8d9..ca09caf 100644 --- a/libs/ui/Input.cpp +++ b/libs/androidfw/Input.cpp @@ -24,7 +24,7 @@ #include <unistd.h> #include <ctype.h> -#include <ui/Input.h> +#include <androidfw/Input.h> #include <math.h> #include <limits.h> diff --git a/libs/ui/InputTransport.cpp b/libs/androidfw/InputTransport.cpp index ecb3fb5..1ebd75c 100644 --- a/libs/ui/InputTransport.cpp +++ b/libs/androidfw/InputTransport.cpp @@ -20,7 +20,7 @@ #include <cutils/log.h> #include <errno.h> #include <fcntl.h> -#include <ui/InputTransport.h> +#include <androidfw/InputTransport.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/androidfw/KeyCharacterMap.cpp index 485234c..6984084 100644 --- a/libs/ui/KeyCharacterMap.cpp +++ b/libs/androidfw/KeyCharacterMap.cpp @@ -19,8 +19,8 @@ #include <stdlib.h> #include <string.h> #include <android/keycodes.h> -#include <ui/Keyboard.h> -#include <ui/KeyCharacterMap.h> +#include <androidfw/Keyboard.h> +#include <androidfw/KeyCharacterMap.h> #include <utils/Log.h> #include <utils/Errors.h> #include <utils/Tokenizer.h> diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/androidfw/KeyLayoutMap.cpp index 44a9420..15d81ee 100644 --- a/libs/ui/KeyLayoutMap.cpp +++ b/libs/androidfw/KeyLayoutMap.cpp @@ -18,8 +18,8 @@ #include <stdlib.h> #include <android/keycodes.h> -#include <ui/Keyboard.h> -#include <ui/KeyLayoutMap.h> +#include <androidfw/Keyboard.h> +#include <androidfw/KeyLayoutMap.h> #include <utils/Log.h> #include <utils/Errors.h> #include <utils/Tokenizer.h> diff --git a/libs/ui/Keyboard.cpp b/libs/androidfw/Keyboard.cpp index e4611f7..e97a5eb 100644 --- a/libs/ui/Keyboard.cpp +++ b/libs/androidfw/Keyboard.cpp @@ -20,10 +20,10 @@ #include <unistd.h> #include <limits.h> -#include <ui/Keyboard.h> -#include <ui/KeycodeLabels.h> -#include <ui/KeyLayoutMap.h> -#include <ui/KeyCharacterMap.h> +#include <androidfw/Keyboard.h> +#include <androidfw/KeycodeLabels.h> +#include <androidfw/KeyLayoutMap.h> +#include <androidfw/KeyCharacterMap.h> #include <utils/Errors.h> #include <utils/Log.h> #include <cutils/properties.h> diff --git a/libs/androidfw/MODULE_LICENSE_APACHE2 b/libs/androidfw/MODULE_LICENSE_APACHE2 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/libs/androidfw/MODULE_LICENSE_APACHE2 diff --git a/libs/androidfw/NOTICE b/libs/androidfw/NOTICE new file mode 100644 index 0000000..c5b1efa --- /dev/null +++ b/libs/androidfw/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, 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. + + 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. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/libs/utils/ObbFile.cpp b/libs/androidfw/ObbFile.cpp index ddf5991..21e06c8 100644 --- a/libs/utils/ObbFile.cpp +++ b/libs/androidfw/ObbFile.cpp @@ -23,9 +23,9 @@ #define LOG_TAG "ObbFile" +#include <androidfw/ObbFile.h> #include <utils/Compat.h> #include <utils/Log.h> -#include <utils/ObbFile.h> //#define DEBUG 1 diff --git a/libs/utils/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 3fa562e..07f3b16 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -17,14 +17,14 @@ #define LOG_TAG "ResourceType" //#define LOG_NDEBUG 0 +#include <androidfw/ResourceTypes.h> #include <utils/Atomic.h> #include <utils/ByteOrder.h> #include <utils/Debug.h> -#include <utils/ResourceTypes.h> +#include <utils/Log.h> #include <utils/String16.h> #include <utils/String8.h> #include <utils/TextOutput.h> -#include <utils/Log.h> #include <stdlib.h> #include <string.h> @@ -379,8 +379,7 @@ status_t ResStringPool::setTo(const void* data, size_t size, bool copyData) size_t charSize; if (mHeader->flags&ResStringPool_header::UTF8_FLAG) { charSize = sizeof(uint8_t); - mCache = (char16_t**)malloc(sizeof(char16_t**)*mHeader->stringCount); - memset(mCache, 0, sizeof(char16_t**)*mHeader->stringCount); + mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**)); } else { charSize = sizeof(char16_t); } @@ -3252,16 +3251,14 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag, // Bag not found, we need to compute it! if (!grp->bags) { - grp->bags = (bag_set***)malloc(sizeof(bag_set*)*grp->typeCount); + grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*)); if (!grp->bags) return NO_MEMORY; - memset(grp->bags, 0, sizeof(bag_set*)*grp->typeCount); } bag_set** typeSet = grp->bags[t]; if (!typeSet) { - typeSet = (bag_set**)malloc(sizeof(bag_set*)*NENTRY); + typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*)); if (!typeSet) return NO_MEMORY; - memset(typeSet, 0, sizeof(bag_set*)*NENTRY); grp->bags[t] = typeSet; } diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/androidfw/StreamingZipInflater.cpp index 8512170..d3fb98d 100644 --- a/libs/utils/StreamingZipInflater.cpp +++ b/libs/androidfw/StreamingZipInflater.cpp @@ -18,8 +18,8 @@ #define LOG_TAG "szipinf" #include <utils/Log.h> +#include <androidfw/StreamingZipInflater.h> #include <utils/FileMap.h> -#include <utils/StreamingZipInflater.h> #include <string.h> #include <stddef.h> #include <assert.h> diff --git a/libs/ui/VirtualKeyMap.cpp b/libs/androidfw/VirtualKeyMap.cpp index 62d5b59..2ba1673 100644 --- a/libs/ui/VirtualKeyMap.cpp +++ b/libs/androidfw/VirtualKeyMap.cpp @@ -18,7 +18,7 @@ #include <stdlib.h> #include <string.h> -#include <ui/VirtualKeyMap.h> +#include <androidfw/VirtualKeyMap.h> #include <utils/Log.h> #include <utils/Errors.h> #include <utils/Tokenizer.h> diff --git a/libs/utils/ZipFileCRO.cpp b/libs/androidfw/ZipFileCRO.cpp index 55dfd9f..c8df845 100644 --- a/libs/utils/ZipFileCRO.cpp +++ b/libs/androidfw/ZipFileCRO.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#include <utils/ZipFileCRO.h> -#include <utils/ZipFileRO.h> +#include <androidfw/ZipFileCRO.h> +#include <androidfw/ZipFileRO.h> using namespace android; diff --git a/libs/utils/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp index 1498aac..4b7f1e7 100644 --- a/libs/utils/ZipFileRO.cpp +++ b/libs/androidfw/ZipFileRO.cpp @@ -19,7 +19,7 @@ // #define LOG_TAG "zipro" //#define LOG_NDEBUG 0 -#include <utils/ZipFileRO.h> +#include <androidfw/ZipFileRO.h> #include <utils/Log.h> #include <utils/misc.h> #include <utils/threads.h> diff --git a/libs/utils/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp index 2dbdc1d..db3479d 100644 --- a/libs/utils/ZipUtils.cpp +++ b/libs/androidfw/ZipUtils.cpp @@ -20,8 +20,8 @@ #define LOG_TAG "ziputil" -#include <utils/ZipUtils.h> -#include <utils/ZipFileRO.h> +#include <androidfw/ZipUtils.h> +#include <androidfw/ZipFileRO.h> #include <utils/Log.h> #include <stdlib.h> diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk new file mode 100644 index 0000000..d85009b --- /dev/null +++ b/libs/androidfw/tests/Android.mk @@ -0,0 +1,47 @@ +# Build the unit tests. +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +# Build the unit tests. +test_src_files := \ + InputChannel_test.cpp \ + InputEvent_test.cpp \ + InputPublisherAndConsumer_test.cpp \ + ObbFile_test.cpp \ + ZipFileRO_test.cpp + +shared_libraries := \ + libandroidfw \ + libcutils \ + libutils \ + libbinder \ + libui \ + libstlport \ + libskia + +static_libraries := \ + libgtest \ + libgtest_main + +c_includes := \ + bionic \ + bionic/libstdc++/include \ + external/gtest/include \ + external/stlport/stlport \ + external/skia/include/core + +module_tags := eng tests + +$(foreach file,$(test_src_files), \ + $(eval include $(CLEAR_VARS)) \ + $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ + $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ + $(eval LOCAL_C_INCLUDES := $(c_includes)) \ + $(eval LOCAL_SRC_FILES := $(file)) \ + $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ + $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ + $(eval include $(BUILD_EXECUTABLE)) \ +) + +# Build the manual test programs. +include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/androidfw/tests/InputChannel_test.cpp index ee422fe..0e5d19d 100644 --- a/libs/ui/tests/InputChannel_test.cpp +++ b/libs/androidfw/tests/InputChannel_test.cpp @@ -14,9 +14,10 @@ * limitations under the License. */ -#include <ui/InputTransport.h> +#include <androidfw/InputTransport.h> #include <utils/Timers.h> #include <utils/StopWatch.h> +#include <utils/StrongPointer.h> #include <gtest/gtest.h> #include <unistd.h> #include <time.h> diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/androidfw/tests/InputEvent_test.cpp index e21c464..ac5549c 100644 --- a/libs/ui/tests/InputEvent_test.cpp +++ b/libs/androidfw/tests/InputEvent_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <ui/Input.h> +#include <androidfw/Input.h> #include <gtest/gtest.h> #include <binder/Parcel.h> diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp index 3303053..bb45247 100644 --- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp +++ b/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <ui/InputTransport.h> +#include <androidfw/InputTransport.h> #include <utils/Timers.h> #include <utils/StopWatch.h> #include <gtest/gtest.h> diff --git a/libs/utils/tests/ObbFile_test.cpp b/libs/androidfw/tests/ObbFile_test.cpp index 46b30c2..09d4d7d 100644 --- a/libs/utils/tests/ObbFile_test.cpp +++ b/libs/androidfw/tests/ObbFile_test.cpp @@ -15,8 +15,8 @@ */ #define LOG_TAG "ObbFile_test" +#include <androidfw/ObbFile.h> #include <utils/Log.h> -#include <utils/ObbFile.h> #include <utils/RefBase.h> #include <utils/String8.h> diff --git a/libs/utils/tests/ZipFileRO_test.cpp b/libs/androidfw/tests/ZipFileRO_test.cpp index 7a1d0bd..344f974 100644 --- a/libs/utils/tests/ZipFileRO_test.cpp +++ b/libs/androidfw/tests/ZipFileRO_test.cpp @@ -15,8 +15,8 @@ */ #define LOG_TAG "ZipFileRO_test" +#include <androidfw/ZipFileRO.h> #include <utils/Log.h> -#include <utils/ZipFileRO.h> #include <gtest/gtest.h> diff --git a/libs/common_time/Android.mk b/libs/common_time/Android.mk new file mode 100644 index 0000000..526f17b --- /dev/null +++ b/libs/common_time/Android.mk @@ -0,0 +1,21 @@ +LOCAL_PATH:= $(call my-dir) +# +# libcommon_time_client +# (binder marshalers for ICommonClock as well as common clock and local clock +# helper code) +# + +include $(CLEAR_VARS) + +LOCAL_MODULE := libcommon_time_client +LOCAL_MODULE_TAGS := optional +LOCAL_SRC_FILES := cc_helper.cpp \ + local_clock.cpp \ + ICommonClock.cpp \ + ICommonTimeConfig.cpp \ + utils.cpp +LOCAL_SHARED_LIBRARIES := libbinder \ + libhardware \ + libutils + +include $(BUILD_SHARED_LIBRARY) diff --git a/libs/common_time/ICommonClock.cpp b/libs/common_time/ICommonClock.cpp new file mode 100644 index 0000000..28b43ac --- /dev/null +++ b/libs/common_time/ICommonClock.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2012 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 <linux/socket.h> + +#include <common_time/ICommonClock.h> +#include <binder/Parcel.h> + +#include "utils.h" + +namespace android { + +/***** ICommonClock *****/ + +enum { + IS_COMMON_TIME_VALID = IBinder::FIRST_CALL_TRANSACTION, + COMMON_TIME_TO_LOCAL_TIME, + LOCAL_TIME_TO_COMMON_TIME, + GET_COMMON_TIME, + GET_COMMON_FREQ, + GET_LOCAL_TIME, + GET_LOCAL_FREQ, + GET_ESTIMATED_ERROR, + GET_TIMELINE_ID, + GET_STATE, + GET_MASTER_ADDRESS, + REGISTER_LISTENER, + UNREGISTER_LISTENER, +}; + +const String16 ICommonClock::kServiceName("common_time.clock"); +const uint64_t ICommonClock::kInvalidTimelineID = 0; +const int32_t ICommonClock::kErrorEstimateUnknown = 0x7FFFFFFF; + +class BpCommonClock : public BpInterface<ICommonClock> +{ + public: + BpCommonClock(const sp<IBinder>& impl) + : BpInterface<ICommonClock>(impl) {} + + virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(IS_COMMON_TIME_VALID, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *valid = reply.readInt32(); + *timelineID = reply.readInt32(); + } + } + return status; + } + + virtual status_t commonTimeToLocalTime(int64_t commonTime, + int64_t* localTime) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + data.writeInt64(commonTime); + status_t status = remote()->transact(COMMON_TIME_TO_LOCAL_TIME, + data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *localTime = reply.readInt64(); + } + } + return status; + } + + virtual status_t localTimeToCommonTime(int64_t localTime, + int64_t* commonTime) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + data.writeInt64(localTime); + status_t status = remote()->transact(LOCAL_TIME_TO_COMMON_TIME, + data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *commonTime = reply.readInt64(); + } + } + return status; + } + + virtual status_t getCommonTime(int64_t* commonTime) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_COMMON_TIME, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *commonTime = reply.readInt64(); + } + } + return status; + } + + virtual status_t getCommonFreq(uint64_t* freq) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_COMMON_FREQ, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *freq = reply.readInt64(); + } + } + return status; + } + + virtual status_t getLocalTime(int64_t* localTime) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_LOCAL_TIME, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *localTime = reply.readInt64(); + } + } + return status; + } + + virtual status_t getLocalFreq(uint64_t* freq) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_LOCAL_FREQ, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *freq = reply.readInt64(); + } + } + return status; + } + + virtual status_t getEstimatedError(int32_t* estimate) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_ESTIMATED_ERROR, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *estimate = reply.readInt32(); + } + } + return status; + } + + virtual status_t getTimelineID(uint64_t* id) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_TIMELINE_ID, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *id = static_cast<uint64_t>(reply.readInt64()); + } + } + return status; + } + + virtual status_t getState(State* state) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_STATE, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *state = static_cast<State>(reply.readInt32()); + } + } + return status; + } + + virtual status_t getMasterAddr(struct sockaddr_storage* addr) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_MASTER_ADDRESS, data, &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) + deserializeSockaddr(&reply, addr); + } + return status; + } + + virtual status_t registerListener( + const sp<ICommonClockListener>& listener) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + data.writeStrongBinder(listener->asBinder()); + + status_t status = remote()->transact(REGISTER_LISTENER, data, &reply); + + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t unregisterListener( + const sp<ICommonClockListener>& listener) { + Parcel data, reply; + data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); + data.writeStrongBinder(listener->asBinder()); + status_t status = remote()->transact(UNREGISTER_LISTENER, data, &reply); + + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } +}; + +IMPLEMENT_META_INTERFACE(CommonClock, "android.os.ICommonClock"); + +status_t BnCommonClock::onTransact(uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags) { + switch(code) { + case IS_COMMON_TIME_VALID: { + CHECK_INTERFACE(ICommonClock, data, reply); + bool valid; + uint32_t timelineID; + status_t status = isCommonTimeValid(&valid, &timelineID); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(valid); + reply->writeInt32(timelineID); + } + return OK; + } break; + + case COMMON_TIME_TO_LOCAL_TIME: { + CHECK_INTERFACE(ICommonClock, data, reply); + int64_t commonTime = data.readInt64(); + int64_t localTime; + status_t status = commonTimeToLocalTime(commonTime, &localTime); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(localTime); + } + return OK; + } break; + + case LOCAL_TIME_TO_COMMON_TIME: { + CHECK_INTERFACE(ICommonClock, data, reply); + int64_t localTime = data.readInt64(); + int64_t commonTime; + status_t status = localTimeToCommonTime(localTime, &commonTime); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(commonTime); + } + return OK; + } break; + + case GET_COMMON_TIME: { + CHECK_INTERFACE(ICommonClock, data, reply); + int64_t commonTime; + status_t status = getCommonTime(&commonTime); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(commonTime); + } + return OK; + } break; + + case GET_COMMON_FREQ: { + CHECK_INTERFACE(ICommonClock, data, reply); + uint64_t freq; + status_t status = getCommonFreq(&freq); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(freq); + } + return OK; + } break; + + case GET_LOCAL_TIME: { + CHECK_INTERFACE(ICommonClock, data, reply); + int64_t localTime; + status_t status = getLocalTime(&localTime); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(localTime); + } + return OK; + } break; + + case GET_LOCAL_FREQ: { + CHECK_INTERFACE(ICommonClock, data, reply); + uint64_t freq; + status_t status = getLocalFreq(&freq); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(freq); + } + return OK; + } break; + + case GET_ESTIMATED_ERROR: { + CHECK_INTERFACE(ICommonClock, data, reply); + int32_t error; + status_t status = getEstimatedError(&error); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(error); + } + return OK; + } break; + + case GET_TIMELINE_ID: { + CHECK_INTERFACE(ICommonClock, data, reply); + uint64_t id; + status_t status = getTimelineID(&id); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(static_cast<int64_t>(id)); + } + return OK; + } break; + + case GET_STATE: { + CHECK_INTERFACE(ICommonClock, data, reply); + State state; + status_t status = getState(&state); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(static_cast<int32_t>(state)); + } + return OK; + } break; + + case GET_MASTER_ADDRESS: { + CHECK_INTERFACE(ICommonClock, data, reply); + struct sockaddr_storage addr; + status_t status = getMasterAddr(&addr); + + if ((status == OK) && !canSerializeSockaddr(&addr)) { + status = UNKNOWN_ERROR; + } + + reply->writeInt32(status); + + if (status == OK) { + serializeSockaddr(reply, &addr); + } + + return OK; + } break; + + case REGISTER_LISTENER: { + CHECK_INTERFACE(ICommonClock, data, reply); + sp<ICommonClockListener> listener = + interface_cast<ICommonClockListener>(data.readStrongBinder()); + status_t status = registerListener(listener); + reply->writeInt32(status); + return OK; + } break; + + case UNREGISTER_LISTENER: { + CHECK_INTERFACE(ICommonClock, data, reply); + sp<ICommonClockListener> listener = + interface_cast<ICommonClockListener>(data.readStrongBinder()); + status_t status = unregisterListener(listener); + reply->writeInt32(status); + return OK; + } break; + } + return BBinder::onTransact(code, data, reply, flags); +} + +/***** ICommonClockListener *****/ + +enum { + ON_TIMELINE_CHANGED = IBinder::FIRST_CALL_TRANSACTION, +}; + +class BpCommonClockListener : public BpInterface<ICommonClockListener> +{ + public: + BpCommonClockListener(const sp<IBinder>& impl) + : BpInterface<ICommonClockListener>(impl) {} + + virtual void onTimelineChanged(uint64_t timelineID) { + Parcel data, reply; + data.writeInterfaceToken( + ICommonClockListener::getInterfaceDescriptor()); + data.writeInt64(timelineID); + remote()->transact(ON_TIMELINE_CHANGED, data, &reply); + } +}; + +IMPLEMENT_META_INTERFACE(CommonClockListener, + "android.os.ICommonClockListener"); + +status_t BnCommonClockListener::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { + switch(code) { + case ON_TIMELINE_CHANGED: { + CHECK_INTERFACE(ICommonClockListener, data, reply); + uint32_t timelineID = data.readInt64(); + onTimelineChanged(timelineID); + return NO_ERROR; + } break; + } + + return BBinder::onTransact(code, data, reply, flags); +} + +}; // namespace android diff --git a/libs/common_time/ICommonTimeConfig.cpp b/libs/common_time/ICommonTimeConfig.cpp new file mode 100644 index 0000000..8eb37cb --- /dev/null +++ b/libs/common_time/ICommonTimeConfig.cpp @@ -0,0 +1,508 @@ +/* + * 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 <linux/socket.h> + +#include <common_time/ICommonTimeConfig.h> +#include <binder/Parcel.h> + +#include "utils.h" + +namespace android { + +/***** ICommonTimeConfig *****/ + +enum { + GET_MASTER_ELECTION_PRIORITY = IBinder::FIRST_CALL_TRANSACTION, + SET_MASTER_ELECTION_PRIORITY, + GET_MASTER_ELECTION_ENDPOINT, + SET_MASTER_ELECTION_ENDPOINT, + GET_MASTER_ELECTION_GROUP_ID, + SET_MASTER_ELECTION_GROUP_ID, + GET_INTERFACE_BINDING, + SET_INTERFACE_BINDING, + GET_MASTER_ANNOUNCE_INTERVAL, + SET_MASTER_ANNOUNCE_INTERVAL, + GET_CLIENT_SYNC_INTERVAL, + SET_CLIENT_SYNC_INTERVAL, + GET_PANIC_THRESHOLD, + SET_PANIC_THRESHOLD, + GET_AUTO_DISABLE, + SET_AUTO_DISABLE, + FORCE_NETWORKLESS_MASTER_MODE, +}; + +const String16 ICommonTimeConfig::kServiceName("common_time.config"); + +class BpCommonTimeConfig : public BpInterface<ICommonTimeConfig> +{ + public: + BpCommonTimeConfig(const sp<IBinder>& impl) + : BpInterface<ICommonTimeConfig>(impl) {} + + virtual status_t getMasterElectionPriority(uint8_t *priority) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_MASTER_ELECTION_PRIORITY, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *priority = static_cast<uint8_t>(reply.readInt32()); + } + } + + return status; + } + + virtual status_t setMasterElectionPriority(uint8_t priority) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeInt32(static_cast<int32_t>(priority)); + status_t status = remote()->transact(SET_MASTER_ELECTION_PRIORITY, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_MASTER_ELECTION_ENDPOINT, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + deserializeSockaddr(&reply, addr); + } + } + + return status; + } + + virtual status_t setMasterElectionEndpoint( + const struct sockaddr_storage *addr) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + if (!canSerializeSockaddr(addr)) + return BAD_VALUE; + if (NULL == addr) { + data.writeInt32(0); + } else { + data.writeInt32(1); + serializeSockaddr(&data, addr); + } + status_t status = remote()->transact(SET_MASTER_ELECTION_ENDPOINT, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getMasterElectionGroupId(uint64_t *id) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_MASTER_ELECTION_GROUP_ID, + data, + &reply); + + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *id = static_cast<uint64_t>(reply.readInt64()); + } + } + + return status; + } + + virtual status_t setMasterElectionGroupId(uint64_t id) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeInt64(id); + status_t status = remote()->transact(SET_MASTER_ELECTION_GROUP_ID, + data, + &reply); + + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getInterfaceBinding(String16& ifaceName) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_INTERFACE_BINDING, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + ifaceName = reply.readString16(); + } + } + + return status; + } + + virtual status_t setInterfaceBinding(const String16& ifaceName) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeString16(ifaceName); + status_t status = remote()->transact(SET_INTERFACE_BINDING, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getMasterAnnounceInterval(int *interval) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_MASTER_ANNOUNCE_INTERVAL, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *interval = reply.readInt32(); + } + } + + return status; + } + + virtual status_t setMasterAnnounceInterval(int interval) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeInt32(interval); + status_t status = remote()->transact(SET_MASTER_ANNOUNCE_INTERVAL, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getClientSyncInterval(int *interval) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_CLIENT_SYNC_INTERVAL, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *interval = reply.readInt32(); + } + } + + return status; + } + + virtual status_t setClientSyncInterval(int interval) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeInt32(interval); + status_t status = remote()->transact(SET_CLIENT_SYNC_INTERVAL, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getPanicThreshold(int *threshold) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_PANIC_THRESHOLD, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *threshold = reply.readInt32(); + } + } + + return status; + } + + virtual status_t setPanicThreshold(int threshold) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeInt32(threshold); + status_t status = remote()->transact(SET_PANIC_THRESHOLD, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t getAutoDisable(bool *autoDisable) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_AUTO_DISABLE, + data, + &reply); + if (status == OK) { + status = reply.readInt32(); + if (status == OK) { + *autoDisable = (0 != reply.readInt32()); + } + } + + return status; + } + + virtual status_t setAutoDisable(bool autoDisable) { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + data.writeInt32(autoDisable ? 1 : 0); + status_t status = remote()->transact(SET_AUTO_DISABLE, + data, + &reply); + + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } + + virtual status_t forceNetworklessMasterMode() { + Parcel data, reply; + data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor()); + status_t status = remote()->transact(FORCE_NETWORKLESS_MASTER_MODE, + data, + &reply); + + if (status == OK) { + status = reply.readInt32(); + } + + return status; + } +}; + +IMPLEMENT_META_INTERFACE(CommonTimeConfig, "android.os.ICommonTimeConfig"); + +status_t BnCommonTimeConfig::onTransact(uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags) { + switch(code) { + case GET_MASTER_ELECTION_PRIORITY: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + uint8_t priority; + status_t status = getMasterElectionPriority(&priority); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(static_cast<int32_t>(priority)); + } + return OK; + } break; + + case SET_MASTER_ELECTION_PRIORITY: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + uint8_t priority = static_cast<uint8_t>(data.readInt32()); + status_t status = setMasterElectionPriority(priority); + reply->writeInt32(status); + return OK; + } break; + + case GET_MASTER_ELECTION_ENDPOINT: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + struct sockaddr_storage addr; + status_t status = getMasterElectionEndpoint(&addr); + + if ((status == OK) && !canSerializeSockaddr(&addr)) { + status = UNKNOWN_ERROR; + } + + reply->writeInt32(status); + + if (status == OK) { + serializeSockaddr(reply, &addr); + } + + return OK; + } break; + + case SET_MASTER_ELECTION_ENDPOINT: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + struct sockaddr_storage addr; + int hasAddr = data.readInt32(); + + status_t status; + if (hasAddr) { + deserializeSockaddr(&data, &addr); + status = setMasterElectionEndpoint(&addr); + } else { + status = setMasterElectionEndpoint(&addr); + } + + reply->writeInt32(status); + return OK; + } break; + + case GET_MASTER_ELECTION_GROUP_ID: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + uint64_t id; + status_t status = getMasterElectionGroupId(&id); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt64(id); + } + return OK; + } break; + + case SET_MASTER_ELECTION_GROUP_ID: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + uint64_t id = static_cast<uint64_t>(data.readInt64()); + status_t status = setMasterElectionGroupId(id); + reply->writeInt32(status); + return OK; + } break; + + case GET_INTERFACE_BINDING: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + String16 ret; + status_t status = getInterfaceBinding(ret); + reply->writeInt32(status); + if (status == OK) { + reply->writeString16(ret); + } + return OK; + } break; + + case SET_INTERFACE_BINDING: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + String16 ifaceName; + ifaceName = data.readString16(); + status_t status = setInterfaceBinding(ifaceName); + reply->writeInt32(status); + return OK; + } break; + + case GET_MASTER_ANNOUNCE_INTERVAL: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + int interval; + status_t status = getMasterAnnounceInterval(&interval); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(interval); + } + return OK; + } break; + + case SET_MASTER_ANNOUNCE_INTERVAL: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + int interval = data.readInt32(); + status_t status = setMasterAnnounceInterval(interval); + reply->writeInt32(status); + return OK; + } break; + + case GET_CLIENT_SYNC_INTERVAL: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + int interval; + status_t status = getClientSyncInterval(&interval); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(interval); + } + return OK; + } break; + + case SET_CLIENT_SYNC_INTERVAL: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + int interval = data.readInt32(); + status_t status = setClientSyncInterval(interval); + reply->writeInt32(status); + return OK; + } break; + + case GET_PANIC_THRESHOLD: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + int threshold; + status_t status = getPanicThreshold(&threshold); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(threshold); + } + return OK; + } break; + + case SET_PANIC_THRESHOLD: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + int threshold = data.readInt32(); + status_t status = setPanicThreshold(threshold); + reply->writeInt32(status); + return OK; + } break; + + case GET_AUTO_DISABLE: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + bool autoDisable; + status_t status = getAutoDisable(&autoDisable); + reply->writeInt32(status); + if (status == OK) { + reply->writeInt32(autoDisable ? 1 : 0); + } + return OK; + } break; + + case SET_AUTO_DISABLE: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + bool autoDisable = (0 != data.readInt32()); + status_t status = setAutoDisable(autoDisable); + reply->writeInt32(status); + return OK; + } break; + + case FORCE_NETWORKLESS_MASTER_MODE: { + CHECK_INTERFACE(ICommonTimeConfig, data, reply); + status_t status = forceNetworklessMasterMode(); + reply->writeInt32(status); + return OK; + } break; + } + return BBinder::onTransact(code, data, reply, flags); +} + +}; // namespace android + diff --git a/libs/common_time/cc_helper.cpp b/libs/common_time/cc_helper.cpp new file mode 100644 index 0000000..8d8556c --- /dev/null +++ b/libs/common_time/cc_helper.cpp @@ -0,0 +1,129 @@ +/* + * 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 <stdint.h> + +#include <common_time/cc_helper.h> +#include <common_time/ICommonClock.h> +#include <utils/threads.h> + +namespace android { + +Mutex CCHelper::lock_; +sp<ICommonClock> CCHelper::common_clock_; +sp<ICommonClockListener> CCHelper::common_clock_listener_; +uint32_t CCHelper::ref_count_ = 0; + +bool CCHelper::verifyClock_l() { + bool ret = false; + + if (common_clock_ == NULL) { + common_clock_ = ICommonClock::getInstance(); + if (common_clock_ == NULL) + goto bailout; + } + + if (ref_count_ > 0) { + if (common_clock_listener_ == NULL) { + common_clock_listener_ = new CommonClockListener(); + if (common_clock_listener_ == NULL) + goto bailout; + + if (OK != common_clock_->registerListener(common_clock_listener_)) + goto bailout; + } + } + + ret = true; + +bailout: + if (!ret) { + common_clock_listener_ = NULL; + common_clock_ = NULL; + } + return ret; +} + +CCHelper::CCHelper() { + Mutex::Autolock lock(&lock_); + ref_count_++; + verifyClock_l(); +} + +CCHelper::~CCHelper() { + Mutex::Autolock lock(&lock_); + + assert(ref_count_ > 0); + ref_count_--; + + // If we were the last CCHelper instance in the system, and we had + // previously register a listener, unregister it now so that the common time + // service has the chance to go into auto-disabled mode. + if (!ref_count_ && + (common_clock_ != NULL) && + (common_clock_listener_ != NULL)) { + common_clock_->unregisterListener(common_clock_listener_); + common_clock_listener_ = NULL; + } +} + +void CCHelper::CommonClockListener::onTimelineChanged(uint64_t timelineID) { + // do nothing; listener is only really used as a token so the server can + // find out when clients die. +} + +// Helper methods which attempts to make calls to the common time binder +// service. If the first attempt fails with DEAD_OBJECT, the helpers will +// attempt to make a connection to the service again (assuming that the process +// hosting the service had crashed and the client proxy we are holding is dead) +// If the second attempt fails, or no connection can be made, the we let the +// error propagate up the stack and let the caller deal with the situation as +// best they can. +#define CCHELPER_METHOD(decl, call) \ + status_t CCHelper::decl { \ + Mutex::Autolock lock(&lock_); \ + \ + if (!verifyClock_l()) \ + return DEAD_OBJECT; \ + \ + status_t status = common_clock_->call; \ + if (DEAD_OBJECT == status) { \ + if (!verifyClock_l()) \ + return DEAD_OBJECT; \ + status = common_clock_->call; \ + } \ + \ + return status; \ + } + +#define VERIFY_CLOCK() + +CCHELPER_METHOD(isCommonTimeValid(bool* valid, uint32_t* timelineID), + isCommonTimeValid(valid, timelineID)) +CCHELPER_METHOD(commonTimeToLocalTime(int64_t commonTime, int64_t* localTime), + commonTimeToLocalTime(commonTime, localTime)) +CCHELPER_METHOD(localTimeToCommonTime(int64_t localTime, int64_t* commonTime), + localTimeToCommonTime(localTime, commonTime)) +CCHELPER_METHOD(getCommonTime(int64_t* commonTime), + getCommonTime(commonTime)) +CCHELPER_METHOD(getCommonFreq(uint64_t* freq), + getCommonFreq(freq)) +CCHELPER_METHOD(getLocalTime(int64_t* localTime), + getLocalTime(localTime)) +CCHELPER_METHOD(getLocalFreq(uint64_t* freq), + getLocalFreq(freq)) + +} // namespace android diff --git a/libs/common_time/local_clock.cpp b/libs/common_time/local_clock.cpp new file mode 100644 index 0000000..a7c61fc --- /dev/null +++ b/libs/common_time/local_clock.cpp @@ -0,0 +1,92 @@ +/* + * 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 "common_time" +#include <utils/Log.h> + +#include <assert.h> +#include <stdint.h> + +#include <common_time/local_clock.h> +#include <hardware/hardware.h> +#include <hardware/local_time_hal.h> +#include <utils/Errors.h> +#include <utils/threads.h> + +namespace android { + +Mutex LocalClock::dev_lock_; +local_time_hw_device_t* LocalClock::dev_ = NULL; + +LocalClock::LocalClock() { + int res; + const hw_module_t* mod; + + AutoMutex lock(&dev_lock_); + + if (dev_ != NULL) + return; + + res = hw_get_module_by_class(LOCAL_TIME_HARDWARE_MODULE_ID, NULL, &mod); + if (res) { + ALOGE("Failed to open local time HAL module (res = %d)", res); + } else { + res = local_time_hw_device_open(mod, &dev_); + if (res) { + ALOGE("Failed to open local time HAL device (res = %d)", res); + dev_ = NULL; + } + } +} + +bool LocalClock::initCheck() { + return (NULL != dev_); +} + +int64_t LocalClock::getLocalTime() { + assert(NULL != dev_); + assert(NULL != dev_->get_local_time); + + return dev_->get_local_time(dev_); +} + +uint64_t LocalClock::getLocalFreq() { + assert(NULL != dev_); + assert(NULL != dev_->get_local_freq); + + return dev_->get_local_freq(dev_); +} + +status_t LocalClock::setLocalSlew(int16_t rate) { + assert(NULL != dev_); + + if (!dev_->set_local_slew) + return INVALID_OPERATION; + + return static_cast<status_t>(dev_->set_local_slew(dev_, rate)); +} + +int32_t LocalClock::getDebugLog(struct local_time_debug_event* records, + int max_records) { + assert(NULL != dev_); + + if (!dev_->get_debug_log) + return INVALID_OPERATION; + + return dev_->get_debug_log(dev_, records, max_records); +} + +} // namespace android diff --git a/libs/common_time/utils.cpp b/libs/common_time/utils.cpp new file mode 100644 index 0000000..6539171 --- /dev/null +++ b/libs/common_time/utils.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2012 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 <arpa/inet.h> +#include <linux/socket.h> + +#include <binder/Parcel.h> + +namespace android { + +bool canSerializeSockaddr(const struct sockaddr_storage* addr) { + switch (addr->ss_family) { + case AF_INET: + case AF_INET6: + return true; + default: + return false; + } +} + +void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr) { + switch (addr->ss_family) { + case AF_INET: { + const struct sockaddr_in* s = + reinterpret_cast<const struct sockaddr_in*>(addr); + p->writeInt32(AF_INET); + p->writeInt32(ntohl(s->sin_addr.s_addr)); + p->writeInt32(static_cast<int32_t>(ntohs(s->sin_port))); + } break; + + case AF_INET6: { + const struct sockaddr_in6* s = + reinterpret_cast<const struct sockaddr_in6*>(addr); + const int32_t* a = + reinterpret_cast<const int32_t*>(s->sin6_addr.s6_addr); + p->writeInt32(AF_INET6); + p->writeInt32(ntohl(a[0])); + p->writeInt32(ntohl(a[1])); + p->writeInt32(ntohl(a[2])); + p->writeInt32(ntohl(a[3])); + p->writeInt32(static_cast<int32_t>(ntohs(s->sin6_port))); + p->writeInt32(ntohl(s->sin6_flowinfo)); + p->writeInt32(ntohl(s->sin6_scope_id)); + } break; + } +} + +void deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) { + memset(addr, 0, sizeof(addr)); + + addr->ss_family = p->readInt32(); + switch(addr->ss_family) { + case AF_INET: { + struct sockaddr_in* s = + reinterpret_cast<struct sockaddr_in*>(addr); + s->sin_addr.s_addr = htonl(p->readInt32()); + s->sin_port = htons(static_cast<uint16_t>(p->readInt32())); + } break; + + case AF_INET6: { + struct sockaddr_in6* s = + reinterpret_cast<struct sockaddr_in6*>(addr); + int32_t* a = reinterpret_cast<int32_t*>(s->sin6_addr.s6_addr); + + a[0] = htonl(p->readInt32()); + a[1] = htonl(p->readInt32()); + a[2] = htonl(p->readInt32()); + a[3] = htonl(p->readInt32()); + s->sin6_port = htons(static_cast<uint16_t>(p->readInt32())); + s->sin6_flowinfo = htonl(p->readInt32()); + s->sin6_scope_id = htonl(p->readInt32()); + } break; + } +} + +} // namespace android diff --git a/libs/common_time/utils.h b/libs/common_time/utils.h new file mode 100644 index 0000000..ce79d0d --- /dev/null +++ b/libs/common_time/utils.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_LIBCOMMONCLOCK_UTILS_H +#define ANDROID_LIBCOMMONCLOCK_UTILS_H + +#include <linux/socket.h> + +#include <binder/Parcel.h> +#include <utils/Errors.h> + +namespace android { + +extern bool canSerializeSockaddr(const struct sockaddr_storage* addr); +extern void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr); +extern status_t deserializeSockaddr(const Parcel* p, + struct sockaddr_storage* addr); + +}; // namespace android + +#endif // ANDROID_LIBCOMMONCLOCK_UTILS_H diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h index 16a3d73..55a860e 100644 --- a/libs/hwui/Debug.h +++ b/libs/hwui/Debug.h @@ -30,7 +30,7 @@ #define DEBUG_MEMORY_USAGE 0 // Turn on to enable debugging of cache flushes -#define DEBUG_CACHE_FLUSH 1 +#define DEBUG_CACHE_FLUSH 0 // Turn on to enable layers debugging when rendered as regions #define DEBUG_LAYERS_AS_REGIONS 0 diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index 1a11fbc..8153823 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -61,6 +61,7 @@ const char* DisplayList::OP_NAMES[] = { "DrawLines", "DrawPoints", "DrawText", + "DrawTextOnPath", "DrawPosText", "ResetShader", "SetupShader", @@ -226,6 +227,11 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { while (!mReader.eof()) { int op = mReader.readInt(); + if (op & OP_MAY_BE_SKIPPED_MASK) { + int skip = mReader.readInt(); + ALOGD("%sSkip %d", (char*) indent, skip); + op &= ~OP_MAY_BE_SKIPPED_MASK; + } switch (op) { case DrawGLFunction: { @@ -316,8 +322,9 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { DisplayList* displayList = getDisplayList(); uint32_t width = getUInt(); uint32_t height = getUInt(); - ALOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op], - displayList, width, height, level + 1); + int32_t flags = getInt(); + ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op], + displayList, width, height, flags, level + 1); renderer.outputDisplayList(displayList, level + 1); } break; @@ -477,7 +484,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { break; case DrawText: { getText(&text); - int count = getInt(); + int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); @@ -486,6 +493,17 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { text.text(), text.length(), count, x, y, paint, length); } break; + case DrawTextOnPath: { + getText(&text); + int32_t count = getInt(); + SkPath* path = getPath(); + float hOffset = getFloat(); + float vOffset = getFloat(); + SkPaint* paint = getPaint(renderer); + ALOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], + text.text(), text.length(), count, paint); + } + break; case DrawPosText: { getText(&text); int count = getInt(); @@ -551,7 +569,7 @@ void DisplayList::output(OpenGLRenderer& renderer, uint32_t level) { * 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, Rect& dirty, uint32_t level) { +bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) { bool needsInvalidate = false; TextContainer text; mReader.rewind(); @@ -572,6 +590,18 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) int saveCount = renderer.getSaveCount() - 1; while (!mReader.eof()) { int op = mReader.readInt(); + if (op & OP_MAY_BE_SKIPPED_MASK) { + int32_t skip = mReader.readInt() * 4; + if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) { + mReader.skip(skip); + DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent, + OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip); + continue; + } else { + op &= ~OP_MAY_BE_SKIPPED_MASK; + ALOGD("%s", OP_NAMES[op]); + } + } logBuffer.writeCommand(level, op); switch (op) { @@ -584,7 +614,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case Save: { - int rendererNum = getInt(); + int32_t rendererNum = getInt(); DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum); renderer.save(rendererNum); } @@ -595,7 +625,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case RestoreToCount: { - int restoreCount = saveCount + getInt(); + int32_t restoreCount = saveCount + getInt(); DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount); renderer.restoreToCount(restoreCount); } @@ -606,7 +636,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) float f3 = getFloat(); float f4 = getFloat(); SkPaint* paint = getPaint(renderer); - int flags = getInt(); + int32_t flags = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, paint, flags); renderer.saveLayer(f1, f2, f3, f4, paint, flags); @@ -617,8 +647,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); - int alpha = getInt(); - int flags = getInt(); + int32_t alpha = getInt(); + int32_t flags = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, alpha, flags); renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags); @@ -668,7 +698,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) float f2 = getFloat(); float f3 = getFloat(); float f4 = getFloat(); - int regionOp = getInt(); + int32_t regionOp = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, regionOp); renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp); @@ -678,10 +708,11 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) DisplayList* displayList = getDisplayList(); uint32_t width = getUInt(); uint32_t height = getUInt(); - DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op], - displayList, width, height, level + 1); + 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, height, - dirty, level + 1); + dirty, flags, level + 1); } break; case DrawLayer: { @@ -730,7 +761,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case DrawBitmapMesh: { - int verticesCount = 0; + int32_t verticesCount = 0; uint32_t colorsCount = 0; SkBitmap* bitmap = getBitmap(); @@ -738,7 +769,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) uint32_t meshHeight = getInt(); float* vertices = getFloats(verticesCount); bool hasColors = getInt(); - int* colors = hasColors ? getInts(colorsCount) : NULL; + int32_t* colors = hasColors ? getInts(colorsCount) : NULL; SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); @@ -771,8 +802,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case DrawColor: { - int color = getInt(); - int xferMode = getInt(); + int32_t color = getInt(); + int32_t xferMode = getInt(); DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode); renderer.drawColor(color, (SkXfermode::Mode) xferMode); } @@ -829,7 +860,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) float f4 = getFloat(); float f5 = getFloat(); float f6 = getFloat(); - int i1 = getInt(); + int32_t i1 = getInt(); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p", (char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint); @@ -844,7 +875,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case DrawLines: { - int count = 0; + int32_t count = 0; float* points = getFloats(count); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); @@ -852,7 +883,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case DrawPoints: { - int count = 0; + int32_t count = 0; float* points = getFloats(count); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]); @@ -861,7 +892,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) break; case DrawText: { getText(&text); - int count = getInt(); + int32_t count = getInt(); float x = getFloat(); float y = getFloat(); SkPaint* paint = getPaint(renderer); @@ -871,10 +902,23 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) renderer.drawText(text.text(), text.length(), count, x, y, paint, length); } break; + case DrawTextOnPath: { + getText(&text); + int32_t count = getInt(); + SkPath* path = getPath(); + float hOffset = getFloat(); + float vOffset = getFloat(); + SkPaint* paint = getPaint(renderer); + DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, OP_NAMES[op], + text.text(), text.length(), count, paint); + renderer.drawTextOnPath(text.text(), text.length(), count, path, + hOffset, vOffset, paint); + } + break; case DrawPosText: { getText(&text); - int count = getInt(); - int positionsCount = 0; + int32_t count = getInt(); + int32_t positionsCount = 0; float* positions = getFloats(positionsCount); SkPaint* paint = getPaint(renderer); DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent, @@ -913,7 +957,7 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) float radius = getFloat(); float dx = getFloat(); float dy = getFloat(); - int color = getInt(); + int32_t color = getInt(); DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op], radius, dx, dy, color); renderer.setupShadow(radius, dx, dy, color); @@ -925,8 +969,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) } break; case SetupPaintFilter: { - int clearBits = getInt(); - int setBits = getInt(); + int32_t clearBits = getInt(); + int32_t setBits = getInt(); DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op], clearBits, setBits); renderer.setupPaintFilter(clearBits, setBits); @@ -949,7 +993,8 @@ bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) // Base structure /////////////////////////////////////////////////////////////////////////////// -DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) { +DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), + mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) { } DisplayListRenderer::~DisplayListRenderer() { @@ -1019,6 +1064,7 @@ void DisplayListRenderer::prepareDirty(float left, float top, void DisplayListRenderer::finish() { insertRestoreToCount(); + insertTranlate(); OpenGLRenderer::finish(); } @@ -1043,15 +1089,18 @@ int DisplayListRenderer::save(int flags) { void DisplayListRenderer::restore() { if (mRestoreSaveCount < 0) { - addOp(DisplayList::Restore); - } else { - mRestoreSaveCount--; + restoreToCount(getSaveCount() - 1); + return; } + + mRestoreSaveCount--; + insertTranlate(); OpenGLRenderer::restore(); } void DisplayListRenderer::restoreToCount(int saveCount) { mRestoreSaveCount = saveCount; + insertTranlate(); OpenGLRenderer::restoreToCount(saveCount); } @@ -1074,8 +1123,10 @@ int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, floa } void DisplayListRenderer::translate(float dx, float dy) { - addOp(DisplayList::Translate); - addPoint(dx, dy); + mHasTranslate = true; + mTranslateX += dx; + mTranslateY += dy; + insertRestoreToCount(); OpenGLRenderer::translate(dx, dy); } @@ -1118,12 +1169,15 @@ bool DisplayListRenderer::clipRect(float left, float top, float right, float bot } bool DisplayListRenderer::drawDisplayList(DisplayList* displayList, - uint32_t width, uint32_t height, Rect& dirty, uint32_t level) { + 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 - addOp(DisplayList::DrawDisplayList); + const bool reject = quickReject(0.0f, 0.0f, width, height); + uint32_t* location = addOp(DisplayList::DrawDisplayList, reject); addDisplayList(displayList); addSize(width, height); + addInt(flags); + addSkip(location); return false; } @@ -1134,30 +1188,38 @@ void DisplayListRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pai addPaint(paint); } -void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, - SkPaint* paint) { - addOp(DisplayList::DrawBitmap); +void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) { + const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height()); + uint32_t* location = addOp(DisplayList::DrawBitmap, reject); addBitmap(bitmap); addPoint(left, top); addPaint(paint); + addSkip(location); } -void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, - SkPaint* paint) { - addOp(DisplayList::DrawBitmapMatrix); +void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) { + Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height()); + const mat4 transform(*matrix); + transform.mapRect(r); + + const bool reject = quickReject(r.left, r.top, r.right, r.bottom); + uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject); addBitmap(bitmap); addMatrix(matrix); addPaint(paint); + addSkip(location); } void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint) { - addOp(DisplayList::DrawBitmapRect); + const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom); + uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject); addBitmap(bitmap); addBounds(srcLeft, srcTop, srcRight, srcBottom); addBounds(dstLeft, dstTop, dstRight, dstBottom); addPaint(paint); + addSkip(location); } void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight, @@ -1179,13 +1241,15 @@ void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int me void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs, const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors, float left, float top, float right, float bottom, SkPaint* paint) { - addOp(DisplayList::DrawPatch); + const bool reject = quickReject(left, top, right, bottom); + uint32_t* location = addOp(DisplayList::DrawPatch, reject); addBitmap(bitmap); addInts(xDivs, width); addInts(yDivs, height); addUInts(colors, numColors); addBounds(left, top, right, bottom); addPaint(paint); + addSkip(location); } void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { @@ -1196,17 +1260,23 @@ void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) { void DisplayListRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { - addOp(DisplayList::DrawRect); + const bool reject = paint->getStyle() == SkPaint::kFill_Style && + quickReject(left, top, right, bottom); + uint32_t* location = addOp(DisplayList::DrawRect, reject); addBounds(left, top, right, bottom); addPaint(paint); + addSkip(location); } void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom, float rx, float ry, SkPaint* paint) { - addOp(DisplayList::DrawRoundRect); + const bool reject = paint->getStyle() == SkPaint::kFill_Style && + quickReject(left, top, right, bottom); + uint32_t* location = addOp(DisplayList::DrawRoundRect, reject); addBounds(left, top, right, bottom); addPoint(rx, ry); addPaint(paint); + addSkip(location); } void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) { @@ -1233,9 +1303,15 @@ void DisplayListRenderer::drawArc(float left, float top, float right, float bott } void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) { - addOp(DisplayList::DrawPath); + float left, top, offset; + uint32_t width, height; + computePathBounds(path, paint, left, top, offset, width, height); + + const bool reject = quickReject(left - offset, top - offset, width, height); + uint32_t* location = addOp(DisplayList::DrawPath, reject); addPath(path); addPaint(paint); + addSkip(location); } void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) { @@ -1252,11 +1328,8 @@ void DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) { void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length) { - if (count <= 0) return; - addOp(DisplayList::DrawText); - addText(text, bytesCount); - addInt(count); - addPoint(x, y); + if (!text || count <= 0) return; + // TODO: We should probably make a copy of the paint instead of modifying // it; modifying the paint will change its generationID the first // time, which might impact caches. More investigation needed to @@ -1265,13 +1338,40 @@ void DisplayListRenderer::drawText(const char* text, int bytesCount, int count, // its own copy as it does right now. // Beware: this needs Glyph encoding (already done on the Paint constructor) paint->setAntiAlias(true); + if (length < 0.0f) length = paint->measureText(text, bytesCount); + + bool reject = false; + if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) { + SkPaint::FontMetrics metrics; + paint->getFontMetrics(&metrics, 0.0f); + reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom); + } + + uint32_t* location = addOp(DisplayList::DrawText, reject); + addText(text, bytesCount); + addInt(count); + addPoint(x, y); + addPaint(paint); + addFloat(length); + addSkip(location); +} + +void DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count, + SkPath* path, float hOffset, float vOffset, SkPaint* paint) { + if (!text || count <= 0) return; + addOp(DisplayList::DrawTextOnPath); + addText(text, bytesCount); + addInt(count); + addPath(path); + addFloat(hOffset); + addFloat(vOffset); + paint->setAntiAlias(true); addPaint(paint); - addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length); } void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint) { - if (count <= 0) return; + if (!text || count <= 0) return; addOp(DisplayList::DrawPosText); addText(text, bytesCount); addInt(count); diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 46506e4..5d1b460 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -42,6 +42,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// #define MIN_WRITER_SIZE 4096 +#define OP_MAY_BE_SKIPPED_MASK 0xff000000 // Debug #if DEBUG_DISPLAY_LIST @@ -98,6 +99,7 @@ public: DrawLines, DrawPoints, DrawText, + DrawTextOnPath, DrawPosText, ResetShader, SetupShader, @@ -110,13 +112,18 @@ public: DrawGLFunction, }; + // See flags defined in DisplayList.java + enum ReplayFlag { + kReplayFlag_ClipChildren = 0x1 + }; + static const char* OP_NAMES[]; void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); ANDROID_API size_t getSize(); - bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0); + bool replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0); void output(OpenGLRenderer& renderer, uint32_t level = 0); @@ -167,11 +174,11 @@ private: return (SkiaColorFilter*) getInt(); } - inline int getIndex() { + inline int32_t getIndex() { return mReader.readInt(); } - inline int getInt() { + inline int32_t getInt() { return mReader.readInt(); } @@ -209,7 +216,7 @@ private: return (uint32_t*) mReader.skip(count * sizeof(uint32_t)); } - float* getFloats(int& count) { + float* getFloats(int32_t& count) { count = getInt(); return (float*) mReader.skip(count * sizeof(float)); } @@ -279,7 +286,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, - Rect& dirty, uint32_t level = 0); + 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); virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint); @@ -304,6 +311,8 @@ public: virtual void drawPoints(float* points, int count, SkPaint* paint); virtual void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = 1.0f); + virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + float hOffset, float vOffset, SkPaint* paint); virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, SkPaint* paint); @@ -358,13 +367,45 @@ private: } } - inline void addOp(DisplayList::Op drawOp) { + void insertTranlate() { + if (mHasTranslate) { + if (mTranslateX != 0.0f || mTranslateY != 0.0f) { + mWriter.writeInt(DisplayList::Translate); + addPoint(mTranslateX, mTranslateY); + mTranslateX = mTranslateY = 0.0f; + } + mHasTranslate = false; + } + } + + inline void addOp(const DisplayList::Op drawOp) { insertRestoreToCount(); + insertTranlate(); mWriter.writeInt(drawOp); mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList; } - inline void addInt(int value) { + uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) { + insertRestoreToCount(); + insertTranlate(); + mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList; + if (reject) { + mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp); + mWriter.writeInt(0); + uint32_t* location = reject ? mWriter.peek32(mWriter.size() - 4) : NULL; + return location; + } + mWriter.writeInt(drawOp); + return NULL; + } + + inline void addSkip(uint32_t* location) { + if (location) { + *location = (int32_t) (mWriter.peek32(mWriter.size() - 4) - location); + } + } + + inline void addInt(int32_t value) { mWriter.writeInt(value); } @@ -391,9 +432,9 @@ private: mWriter.writeScalar(value); } - void addFloats(const float* values, int count) { + void addFloats(const float* values, int32_t count) { mWriter.writeInt(count); - for (int i = 0; i < count; i++) { + for (int32_t i = 0; i < count; i++) { mWriter.writeScalar(values[i]); } } @@ -424,7 +465,9 @@ private: SkPath* pathCopy = mPathMap.valueFor(path); if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) { pathCopy = new SkPath(*path); - mPathMap.add(path, pathCopy); + pathCopy->setSourcePath(path); + // replaceValueFor() performs an add if the entry doesn't exist + mPathMap.replaceValueFor(path, pathCopy); mPaths.add(pathCopy); } @@ -440,7 +483,8 @@ private: SkPaint* paintCopy = mPaintMap.valueFor(paint); if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { paintCopy = new SkPaint(*paint); - mPaintMap.add(paint, paintCopy); + // replaceValueFor() performs an add if the entry doesn't exist + mPaintMap.replaceValueFor(paint, paintCopy); mPaints.add(paintCopy); } @@ -482,7 +526,8 @@ private: // TODO: We also need to handle generation ID changes in compose shaders if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) { shaderCopy = shader->copy(); - mShaderMap.add(shader, shaderCopy); + // replaceValueFor() performs an add if the entry doesn't exist + mShaderMap.replaceValueFor(shader, shaderCopy); mShaders.add(shaderCopy); Caches::getInstance().resourceCache.incrementRefcount(shaderCopy); } @@ -513,6 +558,11 @@ private: SkWriter32 mWriter; int mRestoreSaveCount; + + float mTranslateX; + float mTranslateY; + bool mHasTranslate; + bool mHasDrawOps; friend class DisplayList; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index afae70f..ebb6d88 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -21,6 +21,7 @@ #include <sys/types.h> #include <SkCanvas.h> +#include <SkPathMeasure.h> #include <SkTypeface.h> #include <utils/Log.h> @@ -1321,7 +1322,7 @@ void OpenGLRenderer::finishDrawTexture() { /////////////////////////////////////////////////////////////////////////////// bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height, - Rect& dirty, uint32_t level) { + Rect& dirty, int32_t flags, uint32_t level) { if (quickReject(0.0f, 0.0f, width, height)) { return false; } @@ -1329,7 +1330,7 @@ bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, u // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself if (displayList && displayList->isRenderable()) { - return displayList->replay(*this, dirty, level); + return displayList->replay(*this, dirty, flags, level); } return false; @@ -2189,8 +2190,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, SkPaint::FontMetrics metrics; paint->getFontMetrics(&metrics, 0.0f); // If no length was specified, just perform the hit test on the Y axis - if (quickReject(x, y + metrics.fTop, - x + (length >= 0.0f ? length : INT_MAX / 2), y + metrics.fBottom)) { + if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) { return; } @@ -2293,11 +2293,82 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, drawTextDecorations(text, bytesCount, length, oldX, oldY, paint); } +void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + float hOffset, float vOffset, SkPaint* paint) { + if (text == NULL || count == 0 || mSnapshot->isIgnored() || + (paint->getAlpha() == 0 && paint->getXfermode() == NULL)) { + return; + } + + float x = 0.0f; + float y = 0.0f; + + const bool pureTranslate = mSnapshot->transform->isPureTranslate(); + if (CC_LIKELY(pureTranslate)) { + x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f); + y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f); + } + + FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint); + fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), + paint->getTextSize()); + + int alpha; + SkXfermode::Mode mode; + getAlphaAndMode(paint, &alpha, &mode); + + mCaches.activeTexture(0); + setupDraw(); + setupDrawDirtyRegionsDisabled(); + setupDrawWithTexture(true); + setupDrawAlpha8Color(paint->getColor(), alpha); + setupDrawColorFilter(); + setupDrawShader(); + setupDrawBlending(true, mode); + setupDrawProgram(); + setupDrawModelView(x, y, x, y, pureTranslate, true); + setupDrawTexture(fontRenderer.getTexture(true)); + setupDrawPureColorUniforms(); + setupDrawColorFilterUniforms(); + setupDrawShaderUniforms(pureTranslate); + +// mat4 pathTransform; +// pathTransform.loadTranslate(hOffset, vOffset, 0.0f); +// +// float offset = 0.0f; +// SkPathMeasure pathMeasure(*path, false); +// +// if (paint->getTextAlign() != SkPaint::kLeft_Align) { +// SkScalar pathLength = pathMeasure.getLength(); +// if (paint->getTextAlign() == SkPaint::kCenter_Align) { +// pathLength = SkScalarHalf(pathLength); +// } +// offset += SkScalarToFloat(pathLength); +// } + +// SkScalar x; +// SkPath tmp; +// SkMatrix m(scaledMatrix); +// +// m.postTranslate(xpos + hOffset, 0); +// if (matrix) { +// m.postConcat(*matrix); +// } +// morphpath(&tmp, *iterPath, meas, m); +// if (fDevice) { +// fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true); +// } else { +// this->drawPath(tmp, iter.getPaint(), NULL, true); +// } +// } +} + void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { if (mSnapshot->isIgnored()) return; mCaches.activeTexture(0); + // TODO: Perform early clip test before we rasterize the path const PathTexture* texture = mCaches.pathCache.get(path, paint); if (!texture) return; const AutoTexture autoCleanup(texture); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 3c2d09e..4d7a491 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -98,7 +98,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, - Rect& dirty, uint32_t level = 0); + 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); virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint); @@ -124,8 +124,10 @@ public: virtual void drawPoints(float* points, int count, SkPaint* paint); virtual void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint, float length = -1.0f); - virtual void drawPosText(const char* text, int bytesCount, int count, const float* positions, - SkPaint* paint); + virtual void drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path, + float hOffset, float vOffset, SkPaint* paint); + virtual void drawPosText(const char* text, int bytesCount, int count, + const float* positions, SkPaint* paint); virtual void resetShader(); virtual void setupShader(SkiaShader* shader); diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index e893f7a..e363b73 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -24,6 +24,23 @@ namespace android { namespace uirenderer { +// Defined in ShapeCache.h +void computePathBounds(const SkPath *path, const SkPaint* paint, + float& left, float& top, float& offset, uint32_t& width, uint32_t& height) { + const SkRect& bounds = path->getBounds(); + + const float pathWidth = fmax(bounds.width(), 1.0f); + const float pathHeight = fmax(bounds.height(), 1.0f); + + left = bounds.fLeft; + top = bounds.fTop; + + offset = (int) floorf(fmax(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f); + + width = uint32_t(pathWidth + offset * 2.0 + 0.5); + height = uint32_t(pathHeight + offset * 2.0 + 0.5); +} + /////////////////////////////////////////////////////////////////////////////// // Path cache /////////////////////////////////////////////////////////////////////////////// @@ -66,9 +83,17 @@ void PathCache::clearGarbage() { } PathTexture* PathCache::get(SkPath* path, SkPaint* paint) { + const SkPath* sourcePath = path->getSourcePath(); + if (sourcePath && sourcePath->getGenerationID() == path->getGenerationID()) { + path = const_cast<SkPath*>(sourcePath); + } + PathCacheEntry entry(path, paint); PathTexture* texture = mCache.get(entry); + float left, top, offset; + uint32_t width, height; + if (!texture) { texture = addTexture(entry, path, paint); } else if (path->getGenerationID() != texture->generation) { diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h index 30ce690..f180e94 100644 --- a/libs/hwui/ShapeCache.h +++ b/libs/hwui/ShapeCache.h @@ -489,18 +489,16 @@ void ShapeCache<Entry>::removeTexture(PathTexture* texture) { } } +void computePathBounds(const SkPath *path, const SkPaint* paint, + float& left, float& top, float& offset, uint32_t& width, uint32_t& height); + template<class Entry> PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint) { - const SkRect& bounds = path->getBounds(); - - const float pathWidth = fmax(bounds.width(), 1.0f); - const float pathHeight = fmax(bounds.height(), 1.0f); - - const float offset = (int) floorf(fmax(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f); - const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5); - const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5); + float left, top, offset; + uint32_t width, height; + computePathBounds(path, paint, left, top, offset, width, height); if (width > mMaxTextureSize || height > mMaxTextureSize) { ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)", @@ -517,8 +515,8 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat } PathTexture* texture = new PathTexture; - texture->left = bounds.fLeft; - texture->top = bounds.fTop; + texture->left = left; + texture->top = top; texture->offset = offset; texture->width = width; texture->height = height; @@ -542,7 +540,7 @@ PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *pat SkSafeUnref(pathPaint.setXfermode(mode)); SkCanvas canvas(bitmap); - canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset); + canvas.translate(-left + offset, -top + offset); canvas.drawPath(*path, pathPaint); generateTexture(bitmap, texture); diff --git a/libs/rs/Allocation.cpp b/libs/rs/Allocation.cpp new file mode 100644 index 0000000..d69c55f --- /dev/null +++ b/libs/rs/Allocation.cpp @@ -0,0 +1,471 @@ +/* + * Copyright (C) 2008-2012 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 "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" + + +void * Allocation::getIDSafe() const { + //if (mAdaptedAllocation != NULL) { + //return mAdaptedAllocation.getID(); + //} + return getID(); +} + +void Allocation::updateCacheInfo(const Type *t) { + mCurrentDimX = t->getX(); + mCurrentDimY = t->getY(); + mCurrentDimZ = t->getZ(); + mCurrentCount = mCurrentDimX; + if (mCurrentDimY > 1) { + mCurrentCount *= mCurrentDimY; + } + if (mCurrentDimZ > 1) { + mCurrentCount *= mCurrentDimZ; + } +} + +Allocation::Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage) : BaseObj(id, rs) { + if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT | + RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | + RS_ALLOCATION_USAGE_GRAPHICS_VERTEX | + RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS | + RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET | + RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | + RS_ALLOCATION_USAGE_IO_INPUT | + RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) { + ALOGE("Unknown usage specified."); + } + + if ((usage & (RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | + RS_ALLOCATION_USAGE_IO_INPUT)) != 0) { + mWriteAllowed = false; + if ((usage & ~(RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | + RS_ALLOCATION_USAGE_IO_INPUT | + RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE | + RS_ALLOCATION_USAGE_SCRIPT)) != 0) { + ALOGE("Invalid usage combination."); + } + } + + mType = t; + mUsage = usage; + + if (t != NULL) { + updateCacheInfo(t); + } +} + +void Allocation::validateIsInt32() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) { + return; + } + ALOGE("32 bit integer source does not match allocation type %i", dt); +} + +void Allocation::validateIsInt16() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) { + return; + } + ALOGE("16 bit integer source does not match allocation type %i", dt); +} + +void Allocation::validateIsInt8() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) { + return; + } + ALOGE("8 bit integer source does not match allocation type %i", dt); +} + +void Allocation::validateIsFloat32() { + RsDataType dt = mType->getElement()->getDataType(); + if (dt == RS_TYPE_FLOAT_32) { + return; + } + ALOGE("32 bit float source does not match allocation type %i", dt); +} + +void Allocation::validateIsObject() { + RsDataType dt = mType->getElement()->getDataType(); + if ((dt == RS_TYPE_ELEMENT) || + (dt == RS_TYPE_TYPE) || + (dt == RS_TYPE_ALLOCATION) || + (dt == RS_TYPE_SAMPLER) || + (dt == RS_TYPE_SCRIPT) || + (dt == RS_TYPE_MESH) || + (dt == RS_TYPE_PROGRAM_FRAGMENT) || + (dt == RS_TYPE_PROGRAM_VERTEX) || + (dt == RS_TYPE_PROGRAM_RASTER) || + (dt == RS_TYPE_PROGRAM_STORE)) { + return; + } + ALOGE("Object source does not match allocation type %i", dt); +} + +void Allocation::updateFromNative() { + BaseObj::updateFromNative(); + + const void *typeID = rsaAllocationGetType(mRS->mContext, getID()); + if(typeID != NULL) { + const Type *old = mType; + Type *t = new Type((void *)typeID, mRS); + t->updateFromNative(); + updateCacheInfo(t); + mType = t; + delete old; + } +} + +void Allocation::syncAll(RsAllocationUsageType srcLocation) { + switch (srcLocation) { + case RS_ALLOCATION_USAGE_SCRIPT: + case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS: + case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE: + case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX: + break; + default: + ALOGE("Source must be exactly one usage type."); + } + rsAllocationSyncAll(mRS->mContext, getIDSafe(), srcLocation); +} + +void Allocation::ioSendOutput() { + if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) { + ALOGE("Can only send buffer if IO_OUTPUT usage specified."); + } + rsAllocationIoSend(mRS->mContext, getID()); +} + +void Allocation::ioGetInput() { + if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) { + ALOGE("Can only send buffer if IO_OUTPUT usage specified."); + } + rsAllocationIoReceive(mRS->mContext, getID()); +} + +/* +void copyFrom(BaseObj[] d) { + mRS.validate(); + validateIsObject(); + if (d.length != mCurrentCount) { + ALOGE("Array size mismatch, allocation sizeX = " + + mCurrentCount + ", array length = " + d.length); + } + int i[] = new int[d.length]; + for (int ct=0; ct < d.length; ct++) { + i[ct] = d[ct].getID(); + } + copy1DRangeFromUnchecked(0, mCurrentCount, i); +} +*/ + + +/* +void Allocation::setFromFieldPacker(int xoff, FieldPacker fp) { + mRS.validate(); + int eSize = mType.mElement.getSizeBytes(); + final byte[] data = fp.getData(); + + int count = data.length / eSize; + if ((eSize * count) != data.length) { + ALOGE("Field packer length " + data.length + + " not divisible by element size " + eSize + "."); + } + copy1DRangeFromUnchecked(xoff, count, data); +} + +void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) { + mRS.validate(); + if (component_number >= mType.mElement.mElements.length) { + ALOGE("Component_number " + component_number + " out of range."); + } + if(xoff < 0) { + ALOGE("Offset must be >= 0."); + } + + final byte[] data = fp.getData(); + int eSize = mType.mElement.mElements[component_number].getSizeBytes(); + eSize *= mType.mElement.mArraySizes[component_number]; + + if (data.length != eSize) { + ALOGE("Field packer sizelength " + data.length + + " does not match component size " + eSize + "."); + } + + mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD, + component_number, data, data.length); +} +*/ + +void Allocation::generateMipmaps() { + rsAllocationGenerateMipmaps(mRS->mContext, getID()); +} + +void Allocation::copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen) { + if(count < 1) { + ALOGE("Count must be >= 1."); + return; + } + if((off + count) > mCurrentCount) { + ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off); + return; + } + if((count * mType->getElement()->getSizeBytes()) > dataLen) { + ALOGE("Array too small for allocation type."); + return; + } + + rsAllocation1DData(mRS->mContext, getIDSafe(), off, mSelectedLOD, count, data, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int32_t *d, size_t dataLen) { + validateIsInt32(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int16_t *d, size_t dataLen) { + validateIsInt16(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int8_t *d, size_t dataLen) { + validateIsInt8(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const float *d, size_t dataLen) { + validateIsFloat32(); + copy1DRangeFromUnchecked(off, count, d, dataLen); +} + +void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff) { + rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), off, 0, + mSelectedLOD, mSelectedFace, + count, 1, data->getIDSafe(), dataOff, 0, + data->mSelectedLOD, data->mSelectedFace); +} + +void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) { + if (mAdaptedAllocation != NULL) { + + } else { + if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) { + ALOGE("Updated region larger than allocation."); + } + } +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int8_t *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int16_t *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int32_t *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const float *data, size_t dataLen) { + validate2DRange(xoff, yoff, w, h); + rsAllocation2DData(mRS->mContext, getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace, + w, h, data, dataLen); +} + +void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const Allocation *data, size_t dataLen, + uint32_t dataXoff, uint32_t dataYoff) { + validate2DRange(xoff, yoff, w, h); + rsAllocationCopy2DRange(mRS->mContext, getIDSafe(), xoff, yoff, + mSelectedLOD, mSelectedFace, + w, h, data->getIDSafe(), dataXoff, dataYoff, + data->mSelectedLOD, data->mSelectedFace); +} + +/* +void copyTo(byte[] d) { + validateIsInt8(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void copyTo(short[] d) { + validateIsInt16(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void copyTo(int[] d) { + validateIsInt32(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void copyTo(float[] d) { + validateIsFloat32(); + mRS.validate(); + mRS.nAllocationRead(getID(), d); +} + +void resize(int dimX) { + if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { + throw new RSInvalidStateException("Resize only support for 1D allocations at this time."); + } + mRS.nAllocationResize1D(getID(), dimX); + mRS.finish(); // Necessary because resize is fifoed and update is async. + + int typeID = mRS.nAllocationGetType(getID()); + mType = new Type(typeID, mRS); + mType.updateFromNative(); + updateCacheInfo(mType); +} + +void resize(int dimX, int dimY) { + if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) { + throw new RSInvalidStateException( + "Resize only support for 2D allocations at this time."); + } + if (mType.getY() == 0) { + throw new RSInvalidStateException( + "Resize only support for 2D allocations at this time."); + } + mRS.nAllocationResize2D(getID(), dimX, dimY); + mRS.finish(); // Necessary because resize is fifoed and update is async. + + int typeID = mRS.nAllocationGetType(getID()); + mType = new Type(typeID, mRS); + mType.updateFromNative(); + updateCacheInfo(mType); +} +*/ + + +Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage) { + void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, 0); + if (id == 0) { + ALOGE("Allocation creation failed."); + return NULL; + } + return new Allocation(id, rs, type, usage); +} + +Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage, void *pointer) { + void *id = rsAllocationCreateTyped(rs->mContext, type->getID(), mips, usage, (uint32_t)pointer); + if (id == 0) { + ALOGE("Allocation creation failed."); + } + return new Allocation(id, rs, type, usage); +} + +Allocation *Allocation::createTyped(RenderScript *rs, const Type *type, uint32_t usage) { + return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage); +} + +Allocation *Allocation::createSized(RenderScript *rs, const Element *e, size_t count, uint32_t usage) { + Type::Builder b(rs, e); + b.setX(count); + const Type *t = b.create(); + + void *id = rsAllocationCreateTyped(rs->mContext, t->getID(), RS_ALLOCATION_MIPMAP_NONE, usage, 0); + if (id == 0) { + ALOGE("Allocation creation failed."); + } + return new Allocation(id, rs, t, usage); +} + + +/* +SurfaceTexture getSurfaceTexture() { + if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) { + throw new RSInvalidStateException("Allocation is not a surface texture."); + } + + int id = mRS.nAllocationGetSurfaceTextureID(getID()); + return new SurfaceTexture(id); + +} + +void setSurfaceTexture(SurfaceTexture sur) { + if ((mUsage & USAGE_IO_OUTPUT) == 0) { + throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT."); + } + + mRS.validate(); + mRS.nAllocationSetSurfaceTexture(getID(), sur); +} + + +static Allocation createFromBitmapResource(RenderScript rs, + Resources res, + int id, + MipmapControl mips, + int usage) { + + rs.validate(); + Bitmap b = BitmapFactory.decodeResource(res, id); + Allocation alloc = createFromBitmap(rs, b, mips, usage); + b.recycle(); + return alloc; +} + +static Allocation createFromBitmapResource(RenderScript rs, + Resources res, + int id) { + return createFromBitmapResource(rs, res, id, + MipmapControl.MIPMAP_NONE, + USAGE_GRAPHICS_TEXTURE); +} + +static Allocation createFromString(RenderScript rs, + String str, + int usage) { + rs.validate(); + byte[] allocArray = NULL; + try { + allocArray = str.getBytes("UTF-8"); + Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage); + alloc.copyFrom(allocArray); + return alloc; + } + catch (Exception e) { + throw new RSRuntimeException("Could not convert string to utf-8."); + } +} +*/ + diff --git a/libs/rs/Allocation.h b/libs/rs/Allocation.h new file mode 100644 index 0000000..c9e00a4 --- /dev/null +++ b/libs/rs/Allocation.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_ALLOCATION_H__ +#define __ANDROID_ALLOCATION_H__ + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" +#include "Type.h" +#include "Element.h" + +class Allocation : public BaseObj { +protected: + const Type *mType; + uint32_t mUsage; + Allocation *mAdaptedAllocation; + + bool mConstrainedLOD; + bool mConstrainedFace; + bool mConstrainedY; + bool mConstrainedZ; + bool mReadAllowed; + bool mWriteAllowed; + uint32_t mSelectedY; + uint32_t mSelectedZ; + uint32_t mSelectedLOD; + RsAllocationCubemapFace mSelectedFace; + + uint32_t mCurrentDimX; + uint32_t mCurrentDimY; + uint32_t mCurrentDimZ; + uint32_t mCurrentCount; + + + void * getIDSafe() const; + void updateCacheInfo(const Type *t); + + Allocation(void *id, RenderScript *rs, const Type *t, uint32_t usage); + + void validateIsInt32(); + void validateIsInt16(); + void validateIsInt8(); + void validateIsFloat32(); + void validateIsObject(); + + virtual void updateFromNative(); + + void validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h); + +public: + const Type * getType() { + return mType; + } + + void syncAll(RsAllocationUsageType srcLocation); + void ioSendOutput(); + void ioGetInput(); + + //void copyFrom(BaseObj[] d); + //void copyFromUnchecked(int[] d); + //void copyFromUnchecked(short[] d); + //void copyFromUnchecked(byte[] d); + //void copyFromUnchecked(float[] d); + //void copyFrom(int[] d); + //void copyFrom(short[] d); + //void copyFrom(byte[] d); + //void copyFrom(float[] d); + //void setFromFieldPacker(int xoff, FieldPacker fp); + //void setFromFieldPacker(int xoff, int component_number, FieldPacker fp); + void generateMipmaps(); + void copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const int32_t* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const int16_t* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const int8_t* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const float* d, size_t dataLen); + void copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data, uint32_t dataOff); + + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int32_t *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int16_t *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const int8_t *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const float *data, size_t dataLen); + void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, + const Allocation *data, size_t dataLen, + uint32_t dataXoff, uint32_t dataYoff); + + //void copyTo(byte[] d); + //void copyTo(short[] d); + //void copyTo(int[] d); + //void copyTo(float[] d); + void resize(int dimX); + void resize(int dimX, int dimY); + + static Allocation *createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage); + static Allocation *createTyped(RenderScript *rs, const Type *type, + RsAllocationMipmapControl mips, uint32_t usage, void * pointer); + + static Allocation *createTyped(RenderScript *rs, const Type *type, + uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); + static Allocation *createSized(RenderScript *rs, const Element *e, size_t count, + uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); + //SurfaceTexture *getSurfaceTexture(); + //void setSurfaceTexture(SurfaceTexture *sur); + +}; + +#endif diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 9c5d06b..45ed453 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -127,7 +127,14 @@ LOCAL_SRC_FILES:= \ driver/rsdSampler.cpp \ driver/rsdShader.cpp \ driver/rsdShaderCache.cpp \ - driver/rsdVertexArray.cpp + driver/rsdVertexArray.cpp \ + RenderScript.cpp \ + BaseObj.cpp \ + Element.cpp \ + Type.cpp \ + Allocation.cpp \ + Script.cpp \ + ScriptC.cpp LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui diff --git a/libs/rs/BaseObj.cpp b/libs/rs/BaseObj.cpp new file mode 100644 index 0000000..82e51e7 --- /dev/null +++ b/libs/rs/BaseObj.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2008-2012 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 "libRS_cpp" + +#include <rs.h> + +#include "RenderScript.h" +#include "BaseObj.h" + +void * BaseObj::getID() const { + if (mID == NULL) { + ALOGE("Internal error: Object id 0."); + } + return mID; +} + +void * BaseObj::getObjID(const BaseObj *o) { + return o == NULL ? NULL : o->getID(); +} + + +BaseObj::BaseObj(void *id, RenderScript *rs) { + mRS = rs; + mID = id; +} + +void BaseObj::checkValid() { + if (mID == 0) { + ALOGE("Invalid object."); + } +} + +BaseObj::~BaseObj() { + rsObjDestroy(mRS->mContext, mID); + mRS = NULL; + mID = NULL; +} + +void BaseObj::updateFromNative() { + const char *name = NULL; + rsaGetName(mRS, mID, &name); + mName = name; +} + +bool BaseObj::equals(const BaseObj *obj) { + // Early-out check to see if both BaseObjs are actually the same + if (this == obj) + return true; + return mID == obj->mID; +} + + + diff --git a/libs/rs/BaseObj.h b/libs/rs/BaseObj.h new file mode 100644 index 0000000..79761b1 --- /dev/null +++ b/libs/rs/BaseObj.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_BASE_OBJ_H__ +#define __ANDROID_BASE_OBJ_H__ + + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" + +class BaseObj { +protected: + friend class Element; + friend class Type; + friend class Allocation; + friend class Script; + friend class ScriptC; + + void *mID; + RenderScript *mRS; + android::String8 mName; + + void * getID() const; + + BaseObj(void *id, RenderScript *rs); + void checkValid(); + + static void * getObjID(const BaseObj *o); + +public: + + virtual ~BaseObj(); + virtual void updateFromNative(); + virtual bool equals(const BaseObj *obj); +}; + +#endif diff --git a/libs/rs/Element.cpp b/libs/rs/Element.cpp new file mode 100644 index 0000000..f318d40 --- /dev/null +++ b/libs/rs/Element.cpp @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2008-2012 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 "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> +#include <string.h> + +#include "RenderScript.h" +#include "Element.h" + + +const Element * Element::getSubElement(uint32_t index) { + if (!mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mElements[mVisibleElementMap[index]]; +} + +const char * Element::getSubElementName(uint32_t index) { + if (!mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mElementNames[mVisibleElementMap[index]]; +} + +size_t Element::getSubElementArraySize(uint32_t index) { + if (!mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mArraySizes[mVisibleElementMap[index]]; +} + +uint32_t Element::getSubElementOffsetBytes(uint32_t index) { + if (mVisibleElementMap.size()) { + mRS->throwError("Element contains no sub-elements"); + } + if (index >= mVisibleElementMap.size()) { + mRS->throwError("Illegal sub-element index"); + } + return mOffsetInBytes[mVisibleElementMap[index]]; +} + + +#define CREATE_USER(N, T) const Element * Element::N(RenderScript *rs) { \ + return createUser(rs, RS_TYPE_##T); \ +} +CREATE_USER(BOOLEAN, BOOLEAN); +CREATE_USER(U8, UNSIGNED_8); +CREATE_USER(I8, SIGNED_8); +CREATE_USER(U16, UNSIGNED_16); +CREATE_USER(I16, SIGNED_16); +CREATE_USER(U32, UNSIGNED_32); +CREATE_USER(I32, SIGNED_32); +CREATE_USER(U64, UNSIGNED_64); +CREATE_USER(I64, SIGNED_64); +CREATE_USER(F32, FLOAT_32); +CREATE_USER(F64, FLOAT_64); +CREATE_USER(ELEMENT, ELEMENT); +CREATE_USER(TYPE, TYPE); +CREATE_USER(ALLOCATION, ALLOCATION); +CREATE_USER(SAMPLER, SAMPLER); +CREATE_USER(SCRIPT, SCRIPT); +CREATE_USER(MESH, MESH); +CREATE_USER(PROGRAM_FRAGMENT, PROGRAM_FRAGMENT); +CREATE_USER(PROGRAM_VERTEX, PROGRAM_VERTEX); +CREATE_USER(PROGRAM_RASTER, PROGRAM_RASTER); +CREATE_USER(PROGRAM_STORE, PROGRAM_STORE); +CREATE_USER(MATRIX_4X4, MATRIX_4X4); +CREATE_USER(MATRIX_3X3, MATRIX_3X3); +CREATE_USER(MATRIX_2X2, MATRIX_2X2); + +#define CREATE_PIXEL(N, T, K) const Element * Element::N(RenderScript *rs) { \ + return createPixel(rs, RS_TYPE_##T, RS_KIND_##K); \ +} +CREATE_PIXEL(A_8, UNSIGNED_8, PIXEL_A); +CREATE_PIXEL(RGB_565, UNSIGNED_5_6_5, PIXEL_RGB); +CREATE_PIXEL(RGB_888, UNSIGNED_8, PIXEL_RGB); +CREATE_PIXEL(RGBA_4444, UNSIGNED_4_4_4_4, PIXEL_RGBA); +CREATE_PIXEL(RGBA_8888, UNSIGNED_8, PIXEL_RGBA); + +#define CREATE_VECTOR(N, T) const Element * Element::N##_2(RenderScript *rs) { \ + return createVector(rs, RS_TYPE_##T, 2); \ +} \ +const Element * Element::N##_3(RenderScript *rs) { \ + return createVector(rs, RS_TYPE_##T, 3); \ +} \ +const Element * Element::N##_4(RenderScript *rs) { \ + return createVector(rs, RS_TYPE_##T, 4); \ +} +CREATE_VECTOR(U8, UNSIGNED_8); +CREATE_VECTOR(I8, SIGNED_8); +CREATE_VECTOR(U16, UNSIGNED_16); +CREATE_VECTOR(I16, SIGNED_16); +CREATE_VECTOR(U32, UNSIGNED_32); +CREATE_VECTOR(I32, SIGNED_32); +CREATE_VECTOR(U64, UNSIGNED_64); +CREATE_VECTOR(I64, SIGNED_64); +CREATE_VECTOR(F32, FLOAT_32); +CREATE_VECTOR(F64, FLOAT_64); + + +void Element::updateVisibleSubElements() { + if (!mElements.size()) { + return; + } + mVisibleElementMap.clear(); + + int noPaddingFieldCount = 0; + size_t fieldCount = mElementNames.size(); + // Find out how many elements are not padding + for (size_t ct = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].string()[0] != '#') { + noPaddingFieldCount ++; + } + } + + // Make a map that points us at non-padding elements + for (size_t ct = 0; ct < fieldCount; ct ++) { + if (mElementNames[ct].string()[0] != '#') { + mVisibleElementMap.push((uint32_t)ct); + } + } +} + +Element::Element(void *id, RenderScript *rs, + android::Vector<const Element *> &elements, + android::Vector<android::String8> &elementNames, + android::Vector<uint32_t> &arraySizes) : BaseObj(id, rs) { + mSizeBytes = 0; + mVectorSize = 1; + mElements = elements; + mArraySizes = arraySizes; + mElementNames = elementNames; + + mType = RS_TYPE_NONE; + mKind = RS_KIND_USER; + + for (size_t ct = 0; ct < mElements.size(); ct++ ) { + mOffsetInBytes.push(mSizeBytes); + mSizeBytes += mElements[ct]->mSizeBytes * mArraySizes[ct]; + } + updateVisibleSubElements(); +} + + +static uint32_t GetSizeInBytesForType(RsDataType dt) { + switch(dt) { + case RS_TYPE_NONE: + return 0; + case RS_TYPE_SIGNED_8: + case RS_TYPE_UNSIGNED_8: + case RS_TYPE_BOOLEAN: + return 1; + + case RS_TYPE_FLOAT_16: + case RS_TYPE_SIGNED_16: + case RS_TYPE_UNSIGNED_16: + case RS_TYPE_UNSIGNED_5_6_5: + case RS_TYPE_UNSIGNED_5_5_5_1: + case RS_TYPE_UNSIGNED_4_4_4_4: + return 2; + + case RS_TYPE_FLOAT_32: + case RS_TYPE_SIGNED_32: + case RS_TYPE_UNSIGNED_32: + return 4; + + case RS_TYPE_FLOAT_64: + case RS_TYPE_SIGNED_64: + case RS_TYPE_UNSIGNED_64: + return 8; + + case RS_TYPE_MATRIX_4X4: + return 16 * 4; + case RS_TYPE_MATRIX_3X3: + return 9 * 4; + case RS_TYPE_MATRIX_2X2: + return 4 * 4; + + case RS_TYPE_TYPE: + case RS_TYPE_ALLOCATION: + case RS_TYPE_SAMPLER: + case RS_TYPE_SCRIPT: + case RS_TYPE_MESH: + case RS_TYPE_PROGRAM_FRAGMENT: + case RS_TYPE_PROGRAM_VERTEX: + case RS_TYPE_PROGRAM_RASTER: + case RS_TYPE_PROGRAM_STORE: + return 4; + + default: + break; + } + + ALOGE("Missing type %i", dt); + return 0; +} + +Element::Element(void *id, RenderScript *rs, + RsDataType dt, RsDataKind dk, bool norm, uint32_t size) : + BaseObj(id, rs) +{ + uint32_t tsize = GetSizeInBytesForType(dt); + if ((dt != RS_TYPE_UNSIGNED_5_6_5) && + (dt != RS_TYPE_UNSIGNED_4_4_4_4) && + (dt != RS_TYPE_UNSIGNED_5_5_5_1)) { + if (size == 3) { + mSizeBytes = tsize * 4; + } else { + mSizeBytes = tsize * size; + } + } else { + mSizeBytes = tsize; + } + mType = dt; + mKind = dk; + mNormalized = norm; + mVectorSize = size; +} + +Element::~Element() { +} + + /* + Element(int id, RenderScript rs) { + super(id, rs); + } + */ + +void Element::updateFromNative() { + BaseObj::updateFromNative(); +/* + // we will pack mType; mKind; mNormalized; mVectorSize; NumSubElements + int[] dataBuffer = new int[5]; + mRS.nElementGetNativeData(getID(), dataBuffer); + + mNormalized = dataBuffer[2] == 1 ? true : false; + mVectorSize = dataBuffer[3]; + mSize = 0; + for (DataType dt: DataType.values()) { + if(dt.mID == dataBuffer[0]){ + mType = dt; + mSize = mType.mSize * mVectorSize; + } + } + for (DataKind dk: DataKind.values()) { + if(dk.mID == dataBuffer[1]){ + mKind = dk; + } + } + + int numSubElements = dataBuffer[4]; + if(numSubElements > 0) { + mElements = new Element[numSubElements]; + mElementNames = new String[numSubElements]; + mArraySizes = new int[numSubElements]; + mOffsetInBytes = new int[numSubElements]; + + int[] subElementIds = new int[numSubElements]; + mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes); + for(int i = 0; i < numSubElements; i ++) { + mElements[i] = new Element(subElementIds[i], mRS); + mElements[i].updateFromNative(); + mOffsetInBytes[i] = mSize; + mSize += mElements[i].mSize * mArraySizes[i]; + } + } + */ + updateVisibleSubElements(); +} + +const Element * Element::createUser(RenderScript *rs, RsDataType dt) { + void * id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, 1); + return new Element(id, rs, dt, RS_KIND_USER, false, 1); +} + +const Element * Element::createVector(RenderScript *rs, RsDataType dt, uint32_t size) { + if (size < 2 || size > 4) { + rs->throwError("Vector size out of range 2-4."); + } + void *id = rsElementCreate(rs->mContext, dt, RS_KIND_USER, false, size); + return new Element(id, rs, dt, RS_KIND_USER, false, size); +} + +const Element * Element::createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk) { + if (!(dk == RS_KIND_PIXEL_L || + dk == RS_KIND_PIXEL_A || + dk == RS_KIND_PIXEL_LA || + dk == RS_KIND_PIXEL_RGB || + dk == RS_KIND_PIXEL_RGBA || + dk == RS_KIND_PIXEL_DEPTH)) { + rs->throwError("Unsupported DataKind"); + } + if (!(dt == RS_TYPE_UNSIGNED_8 || + dt == RS_TYPE_UNSIGNED_16 || + dt == RS_TYPE_UNSIGNED_5_6_5 || + dt == RS_TYPE_UNSIGNED_4_4_4_4 || + dt == RS_TYPE_UNSIGNED_5_5_5_1)) { + rs->throwError("Unsupported DataType"); + } + if (dt == RS_TYPE_UNSIGNED_5_6_5 && dk != RS_KIND_PIXEL_RGB) { + rs->throwError("Bad kind and type combo"); + } + if (dt == RS_TYPE_UNSIGNED_5_5_5_1 && dk != RS_KIND_PIXEL_RGBA) { + rs->throwError("Bad kind and type combo"); + } + if (dt == RS_TYPE_UNSIGNED_4_4_4_4 && dk != RS_KIND_PIXEL_RGBA) { + rs->throwError("Bad kind and type combo"); + } + if (dt == RS_TYPE_UNSIGNED_16 && dk != RS_KIND_PIXEL_DEPTH) { + rs->throwError("Bad kind and type combo"); + } + + int size = 1; + switch (dk) { + case RS_KIND_PIXEL_LA: + size = 2; + break; + case RS_KIND_PIXEL_RGB: + size = 3; + break; + case RS_KIND_PIXEL_RGBA: + size = 4; + break; + case RS_KIND_PIXEL_DEPTH: + size = 2; + break; + default: + break; + } + + void * id = rsElementCreate(rs->mContext, dt, dk, true, size); + return new Element(id, rs, dt, dk, true, size); +} + +bool Element::isCompatible(const Element *e) { + // Try strict BaseObj equality to start with. + if (this == e) { + return true; + } + + // Ignore mKind because it is allowed to be different (user vs. pixel). + // We also ignore mNormalized because it can be different. The mType + // field must be non-null since we require name equivalence for + // user-created Elements. + return ((mSizeBytes == e->mSizeBytes) && + (mType != NULL) && + (mType == e->mType) && + (mVectorSize == e->mVectorSize)); +} + +Element::Builder::Builder(RenderScript *rs) { + mRS = rs; + mSkipPadding = false; +} + +void Element::Builder::add(const Element *e, android::String8 &name, uint32_t arraySize) { + // Skip padding fields after a vector 3 type. + if (mSkipPadding) { + const char *s1 = "#padding_"; + const char *s2 = name; + size_t len = strlen(s1); + if (strlen(s2) >= len) { + if (!memcmp(s1, s2, len)) { + mSkipPadding = false; + return; + } + } + } + + if (e->mVectorSize == 3) { + mSkipPadding = true; + } else { + mSkipPadding = false; + } + + mElements.add(e); + mElementNames.add(name); + mArraySizes.add(arraySize); +} + +const Element * Element::Builder::create() { + size_t fieldCount = mElements.size(); + const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *)); + size_t* sizeArray = (size_t*)calloc(fieldCount, sizeof(size_t)); + + for (size_t ct = 0; ct < fieldCount; ct++) { + nameArray[ct] = mElementNames[ct].string(); + sizeArray[ct] = mElementNames[ct].length(); + } + + void *id = rsElementCreate2(mRS->mContext, + (RsElement *)mElements.array(), fieldCount, + nameArray, fieldCount * sizeof(size_t), sizeArray, + (const uint32_t *)mArraySizes.array(), fieldCount); + + + free(nameArray); + free(sizeArray); + + Element *e = new Element(id, mRS, mElements, mElementNames, mArraySizes); + return e; +} + diff --git a/libs/rs/Element.h b/libs/rs/Element.h new file mode 100644 index 0000000..a579dc3 --- /dev/null +++ b/libs/rs/Element.h @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_ELEMENT_H__ +#define __ANDROID_ELEMENT_H__ + +#include <rs.h> +#include "RenderScript.h" +#include "BaseObj.h" + +class Element : public BaseObj { +public: + /** + * Return if a element is too complex for use as a data source for a Mesh or + * a Program. + * + * @return boolean + */ + bool isComplex(); + + /** + * @hide + * @return number of sub-elements in this element + */ + size_t getSubElementCount() { + return mVisibleElementMap.size(); + } + + /** + * @hide + * @param index index of the sub-element to return + * @return sub-element in this element at given index + */ + const Element * getSubElement(uint32_t index); + + /** + * @hide + * @param index index of the sub-element + * @return sub-element in this element at given index + */ + const char * getSubElementName(uint32_t index); + + /** + * @hide + * @param index index of the sub-element + * @return array size of sub-element in this element at given index + */ + size_t getSubElementArraySize(uint32_t index); + + /** + * @hide + * @param index index of the sub-element + * @return offset in bytes of sub-element in this element at given index + */ + uint32_t getSubElementOffsetBytes(uint32_t index); + + /** + * @hide + * @return element data type + */ + RsDataType getDataType() const { + return mType; + } + + /** + * @hide + * @return element data kind + */ + RsDataKind getDataKind() const { + return mKind; + } + + size_t getSizeBytes() const { + return mSizeBytes; + } + + + static const Element * BOOLEAN(RenderScript *rs); + static const Element * U8(RenderScript *rs); + static const Element * I8(RenderScript *rs); + static const Element * U16(RenderScript *rs); + static const Element * I16(RenderScript *rs); + static const Element * U32(RenderScript *rs); + static const Element * I32(RenderScript *rs); + static const Element * U64(RenderScript *rs); + static const Element * I64(RenderScript *rs); + static const Element * F32(RenderScript *rs); + static const Element * F64(RenderScript *rs); + static const Element * ELEMENT(RenderScript *rs); + static const Element * TYPE(RenderScript *rs); + static const Element * ALLOCATION(RenderScript *rs); + static const Element * SAMPLER(RenderScript *rs); + static const Element * SCRIPT(RenderScript *rs); + static const Element * MESH(RenderScript *rs); + static const Element * PROGRAM_FRAGMENT(RenderScript *rs); + static const Element * PROGRAM_VERTEX(RenderScript *rs); + static const Element * PROGRAM_RASTER(RenderScript *rs); + static const Element * PROGRAM_STORE(RenderScript *rs); + + static const Element * A_8(RenderScript *rs); + static const Element * RGB_565(RenderScript *rs); + static const Element * RGB_888(RenderScript *rs); + static const Element * RGBA_5551(RenderScript *rs); + static const Element * RGBA_4444(RenderScript *rs); + static const Element * RGBA_8888(RenderScript *rs); + + static const Element * F32_2(RenderScript *rs); + static const Element * F32_3(RenderScript *rs); + static const Element * F32_4(RenderScript *rs); + static const Element * F64_2(RenderScript *rs); + static const Element * F64_3(RenderScript *rs); + static const Element * F64_4(RenderScript *rs); + static const Element * U8_2(RenderScript *rs); + static const Element * U8_3(RenderScript *rs); + static const Element * U8_4(RenderScript *rs); + static const Element * I8_2(RenderScript *rs); + static const Element * I8_3(RenderScript *rs); + static const Element * I8_4(RenderScript *rs); + static const Element * U16_2(RenderScript *rs); + static const Element * U16_3(RenderScript *rs); + static const Element * U16_4(RenderScript *rs); + static const Element * I16_2(RenderScript *rs); + static const Element * I16_3(RenderScript *rs); + static const Element * I16_4(RenderScript *rs); + static const Element * U32_2(RenderScript *rs); + static const Element * U32_3(RenderScript *rs); + static const Element * U32_4(RenderScript *rs); + static const Element * I32_2(RenderScript *rs); + static const Element * I32_3(RenderScript *rs); + static const Element * I32_4(RenderScript *rs); + static const Element * U64_2(RenderScript *rs); + static const Element * U64_3(RenderScript *rs); + static const Element * U64_4(RenderScript *rs); + static const Element * I64_2(RenderScript *rs); + static const Element * I64_3(RenderScript *rs); + static const Element * I64_4(RenderScript *rs); + static const Element * MATRIX_4X4(RenderScript *rs); + static const Element * MATRIX_3X3(RenderScript *rs); + static const Element * MATRIX_2X2(RenderScript *rs); + + Element(void *id, RenderScript *rs, + android::Vector<const Element *> &elements, + android::Vector<android::String8> &elementNames, + android::Vector<uint32_t> &arraySizes); + Element(void *id, RenderScript *rs, RsDataType dt, RsDataKind dk, bool norm, uint32_t size); + Element(RenderScript *rs); + virtual ~Element(); + + void updateFromNative(); + static const Element * createUser(RenderScript *rs, RsDataType dt); + static const Element * createVector(RenderScript *rs, RsDataType dt, uint32_t size); + static const Element * createPixel(RenderScript *rs, RsDataType dt, RsDataKind dk); + bool isCompatible(const Element *e); + + class Builder { + private: + RenderScript *mRS; + android::Vector<const Element *> mElements; + android::Vector<android::String8> mElementNames; + android::Vector<uint32_t> mArraySizes; + bool mSkipPadding; + + public: + Builder(RenderScript *rs); + ~Builder(); + void add(const Element *, android::String8 &name, uint32_t arraySize = 1); + const Element * create(); + }; + +private: + void updateVisibleSubElements(); + + android::Vector<const Element *> mElements; + android::Vector<android::String8> mElementNames; + android::Vector<uint32_t> mArraySizes; + android::Vector<uint32_t> mVisibleElementMap; + android::Vector<uint32_t> mOffsetInBytes; + + RsDataType mType; + RsDataKind mKind; + bool mNormalized; + size_t mSizeBytes; + size_t mVectorSize; +}; + +#endif diff --git a/libs/rs/RenderScript.cpp b/libs/rs/RenderScript.cpp new file mode 100644 index 0000000..0b42055 --- /dev/null +++ b/libs/rs/RenderScript.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2008-2012 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 "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> +#include <string.h> + +#include "RenderScript.h" + +bool RenderScript::gInitialized = false; +pthread_mutex_t RenderScript::gInitMutex = PTHREAD_MUTEX_INITIALIZER; + +RenderScript::RenderScript() { + mDev = NULL; + mContext = NULL; + mErrorFunc = NULL; + mMessageFunc = NULL; + mMessageRun = false; + + memset(&mElements, 0, sizeof(mElements)); +} + +RenderScript::~RenderScript() { + mMessageRun = false; + + rsContextDeinitToClient(mContext); + + void *res = NULL; + int status = pthread_join(mMessageThreadId, &res); + + rsContextDestroy(mContext); + mContext = NULL; + rsDeviceDestroy(mDev); + mDev = NULL; +} + +bool RenderScript::init(int targetApi) { + mDev = rsDeviceCreate(); + if (mDev == 0) { + ALOGE("Device creation failed"); + return false; + } + + mContext = rsContextCreate(mDev, 0, targetApi); + if (mContext == 0) { + ALOGE("Context creation failed"); + return false; + } + + + pid_t mNativeMessageThreadId; + + int status = pthread_create(&mMessageThreadId, NULL, threadProc, this); + if (status) { + ALOGE("Failed to start RenderScript message thread."); + return false; + } + // Wait for the message thread to be active. + while (!mMessageRun) { + usleep(1000); + } + + return true; +} + +void RenderScript::throwError(const char *err) const { + ALOGE("RS CPP error: %s", err); + int * v = NULL; + v[0] = 0; +} + + +void * RenderScript::threadProc(void *vrsc) { + RenderScript *rs = static_cast<RenderScript *>(vrsc); + size_t rbuf_size = 256; + void * rbuf = malloc(rbuf_size); + + rsContextInitToClient(rs->mContext); + rs->mMessageRun = true; + + while (rs->mMessageRun) { + size_t receiveLen = 0; + uint32_t usrID = 0; + uint32_t subID = 0; + RsMessageToClientType r = rsContextPeekMessage(rs->mContext, + &receiveLen, sizeof(receiveLen), + &usrID, sizeof(usrID)); + + if (receiveLen >= rbuf_size) { + rbuf_size = receiveLen + 32; + rbuf = realloc(rbuf, rbuf_size); + } + if (!rbuf) { + ALOGE("RenderScript::message handler realloc error %zu", rbuf_size); + // No clean way to recover now? + } + rsContextGetMessage(rs->mContext, rbuf, rbuf_size, &receiveLen, sizeof(receiveLen), + &subID, sizeof(subID)); + + switch(r) { + case RS_MESSAGE_TO_CLIENT_ERROR: + ALOGE("RS Error %s", (const char *)rbuf); + + if(rs->mMessageFunc != NULL) { + rs->mErrorFunc(usrID, (const char *)rbuf); + } + break; + case RS_MESSAGE_TO_CLIENT_EXCEPTION: + // teardown. But we want to avoid starving other threads during + // teardown by yielding until the next line in the destructor can + // execute to set mRun = false + usleep(1000); + break; + case RS_MESSAGE_TO_CLIENT_USER: + if(rs->mMessageFunc != NULL) { + rs->mMessageFunc(usrID, rbuf, receiveLen); + } else { + ALOGE("Received a message from the script with no message handler installed."); + } + break; + + default: + ALOGE("RenderScript unknown message type %i", r); + } + } + + if (rbuf) { + free(rbuf); + } + ALOGE("RenderScript Message thread exiting."); + return NULL; +} + +void RenderScript::setErrorHandler(ErrorHandlerFunc_t func) { + mErrorFunc = func; +} + +void RenderScript::setMessageHandler(MessageHandlerFunc_t func) { + mMessageFunc = func; +} + +void RenderScript::contextDump() { +} + +void RenderScript::finish() { + +} + + diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index 6d54268..0eb6a6d 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2008-2012 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. @@ -14,58 +14,143 @@ * limitations under the License. */ -#ifndef RENDER_SCRIPT_H -#define RENDER_SCRIPT_H +#ifndef ANDROID_RENDERSCRIPT_H +#define ANDROID_RENDERSCRIPT_H -#include <stdint.h> -#include <sys/types.h> -#ifdef __cplusplus -extern "C" { -#endif +#include <pthread.h> +#include <utils/String8.h> +#include <utils/Vector.h> -#include "RenderScriptDefines.h" - -// -// A3D loading and object update code. -// Should only be called at object creation, not thread safe -RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile); -RsFile rsaFileA3DCreateFromMemory(RsContext, const void *data, uint32_t len); -RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset); -RsFile rsaFileA3DCreateFromFile(RsContext, const char *path); -void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile); -void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries, - uint32_t numEntries, RsFile); -void rsaGetName(RsContext, void * obj, const char **name); -// Mesh update functions -void rsaMeshGetVertexBufferCount(RsContext, RsMesh, int32_t *vtxCount); -void rsaMeshGetIndexCount(RsContext, RsMesh, int32_t *idxCount); -void rsaMeshGetVertices(RsContext, RsMesh, RsAllocation *vtxData, uint32_t vtxDataCount); -void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va, - uint32_t *primType, uint32_t idxDataCount); -// Allocation update -const void* rsaAllocationGetType(RsContext con, RsAllocation va); -// Type update -void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize); -// Element update -void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize); -void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, - uint32_t *arraySizes, uint32_t dataSize); - -RsDevice rsDeviceCreate(); -void rsDeviceDestroy(RsDevice dev); -void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value); -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" - -#ifdef __cplusplus -}; -#endif +#include "rs.h" + +class Element; +class Type; +class Allocation; + +class RenderScript { + friend class BaseObj; + friend class Allocation; + friend class Element; + friend class Type; + friend class Script; + friend class ScriptC; + +public: + RenderScript(); + virtual ~RenderScript(); + + typedef void (*ErrorHandlerFunc_t)(uint32_t errorNum, const char *errorText); + typedef void (*MessageHandlerFunc_t)(uint32_t msgNum, const void *msgData, size_t msgLen); + + + void setErrorHandler(ErrorHandlerFunc_t func); + ErrorHandlerFunc_t getErrorHandler() {return mErrorFunc;} + + void setMessageHandler(MessageHandlerFunc_t func); + MessageHandlerFunc_t getMessageHandler() {return mMessageFunc;} + + bool init(int targetApi); + void contextDump(); + void finish(); + +private: + static bool gInitialized; + static pthread_mutex_t gInitMutex; + + pthread_t mMessageThreadId; + pid_t mNativeMessageThreadId; + bool mMessageRun; + + RsDevice mDev; + RsContext mContext; + + ErrorHandlerFunc_t mErrorFunc; + MessageHandlerFunc_t mMessageFunc; + + struct { + Element *U8; + Element *I8; + Element *U16; + Element *I16; + Element *U32; + Element *I32; + Element *U64; + Element *I64; + Element *F32; + Element *F64; + Element *BOOLEAN; + + Element *ELEMENT; + Element *TYPE; + Element *ALLOCATION; + Element *SAMPLER; + Element *SCRIPT; + Element *MESH; + Element *PROGRAM_FRAGMENT; + Element *PROGRAM_VERTEX; + Element *PROGRAM_RASTER; + Element *PROGRAM_STORE; -#endif // RENDER_SCRIPT_H + Element *A_8; + Element *RGB_565; + Element *RGB_888; + Element *RGBA_5551; + Element *RGBA_4444; + Element *RGBA_8888; + Element *FLOAT_2; + Element *FLOAT_3; + Element *FLOAT_4; + Element *DOUBLE_2; + Element *DOUBLE_3; + Element *DOUBLE_4; + + Element *UCHAR_2; + Element *UCHAR_3; + Element *UCHAR_4; + + Element *CHAR_2; + Element *CHAR_3; + Element *CHAR_4; + + Element *USHORT_2; + Element *USHORT_3; + Element *USHORT_4; + + Element *SHORT_2; + Element *SHORT_3; + Element *SHORT_4; + + Element *UINT_2; + Element *UINT_3; + Element *UINT_4; + + Element *INT_2; + Element *INT_3; + Element *INT_4; + + Element *ULONG_2; + Element *ULONG_3; + Element *ULONG_4; + + Element *LONG_2; + Element *LONG_3; + Element *LONG_4; + + Element *MATRIX_4X4; + Element *MATRIX_3X3; + Element *MATRIX_2X2; + } mElements; + + + + void throwError(const char *err) const; + + static void * threadProc(void *); + +}; + +#endif diff --git a/libs/rs/Script.cpp b/libs/rs/Script.cpp new file mode 100644 index 0000000..25fa673 --- /dev/null +++ b/libs/rs/Script.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008-2012 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 "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" +#include "Script.h" + +void Script::invoke(uint32_t slot, const void *v, size_t len) { + rsScriptInvokeV(mRS->mContext, getID(), slot, v, len); +} + +void Script::forEach(uint32_t slot, const Allocation *ain, const Allocation *aout, + const void *usr, size_t usrLen) { + if ((ain == NULL) && (aout == NULL)) { + mRS->throwError("At least one of ain or aout is required to be non-null."); + } + void *in_id = BaseObj::getObjID(ain); + void *out_id = BaseObj::getObjID(aout); + rsScriptForEach(mRS->mContext, getID(), slot, in_id, out_id, usr, usrLen); +} + + +Script::Script(void *id, RenderScript *rs) : BaseObj(id, rs) { +} + + +void Script::bindAllocation(const Allocation *va, uint32_t slot) { + rsScriptBindAllocation(mRS->mContext, getID(), BaseObj::getObjID(va), slot); +} + + +void Script::setVar(uint32_t index, const BaseObj *o) { + rsScriptSetVarObj(mRS->mContext, getID(), index, (o == NULL) ? 0 : o->getID()); +} + +void Script::setVar(uint32_t index, const void *v, size_t len) { + rsScriptSetVarV(mRS->mContext, getID(), index, v, len); +} + + + +void Script::FieldBase::init(RenderScript *rs, uint32_t dimx, uint32_t usages) { + mAllocation = Allocation::createSized(rs, mElement, dimx, RS_ALLOCATION_USAGE_SCRIPT | usages); +} + +//Script::FieldBase::FieldBase() { +//} + + diff --git a/libs/rs/Script.h b/libs/rs/Script.h new file mode 100644 index 0000000..54d1e40 --- /dev/null +++ b/libs/rs/Script.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_SCRIPT_H__ +#define __ANDROID_SCRIPT_H__ + +#include <pthread.h> +#include <rs.h> + +#include "RenderScript.h" +#include "Allocation.h" + +class Type; +class Element; +class Allocation; + +class Script : public BaseObj { +protected: + Script(void *id, RenderScript *rs); + void forEach(uint32_t slot, const Allocation *in, const Allocation *out, const void *v, size_t); + void bindAllocation(const Allocation *va, uint32_t slot); + void setVar(uint32_t index, const void *, size_t len); + void setVar(uint32_t index, const BaseObj *o); + void invoke(uint32_t slot, const void *v, size_t len); + + + void invoke(uint32_t slot) { + invoke(slot, NULL, 0); + } + void setVar(uint32_t index, float v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, double v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, int32_t v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, int64_t v) { + setVar(index, &v, sizeof(v)); + } + void setVar(uint32_t index, bool v) { + setVar(index, &v, sizeof(v)); + } + +public: + class FieldBase { + protected: + const Element *mElement; + Allocation *mAllocation; + + void init(RenderScript *rs, uint32_t dimx, uint32_t usages = 0); + + public: + const Element *getElement() { + return mElement; + } + + const Type *getType() { + return mAllocation->getType(); + } + + const Allocation *getAllocation() { + return mAllocation; + } + + //void updateAllocation(); + }; +}; + +#endif diff --git a/libs/rs/ScriptC.cpp b/libs/rs/ScriptC.cpp new file mode 100644 index 0000000..ad82ff4 --- /dev/null +++ b/libs/rs/ScriptC.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008-2012 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 "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> + +#include "ScriptC.h" + +ScriptC::ScriptC(RenderScript *rs, + const char *codeTxt, size_t codeLength, + const char *cachedName, size_t cachedNameLength, + const char *cacheDir, size_t cacheDirLength) +: Script(NULL, rs) { + mID = rsScriptCCreate(rs->mContext, cachedName, cachedNameLength, + cacheDir, cacheDirLength, codeTxt, codeLength); +} + diff --git a/libs/rs/ScriptC.h b/libs/rs/ScriptC.h new file mode 100644 index 0000000..dcbbe10 --- /dev/null +++ b/libs/rs/ScriptC.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_SCRIPTC_H__ +#define __ANDROID_SCRIPTC_H__ + +#include <pthread.h> +#include <rs.h> + +#include "Script.h" + +class ScriptC : public Script { +protected: + ScriptC(RenderScript *rs, + const char *codeTxt, size_t codeLength, + const char *cachedName, size_t cachedNameLength, + const char *cacheDir, size_t cacheDirLength); + +}; + +#endif diff --git a/libs/rs/Type.cpp b/libs/rs/Type.cpp new file mode 100644 index 0000000..1352bd7 --- /dev/null +++ b/libs/rs/Type.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2008 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 "libRS_cpp" + +#include <utils/Log.h> +#include <malloc.h> +#include <string.h> + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" + +void Type::calcElementCount() { + bool hasLod = hasMipmaps(); + uint32_t x = getX(); + uint32_t y = getY(); + uint32_t z = getZ(); + uint32_t faces = 1; + if (hasFaces()) { + faces = 6; + } + if (x == 0) { + x = 1; + } + if (y == 0) { + y = 1; + } + if (z == 0) { + z = 1; + } + + uint32_t count = x * y * z * faces; + while (hasLod && ((x > 1) || (y > 1) || (z > 1))) { + if(x > 1) { + x >>= 1; + } + if(y > 1) { + y >>= 1; + } + if(z > 1) { + z >>= 1; + } + + count += x * y * z * faces; + } + mElementCount = count; +} + + +Type::Type(void *id, RenderScript *rs) : BaseObj(id, rs) { + mDimX = 0; + mDimY = 0; + mDimZ = 0; + mDimMipmaps = false; + mDimFaces = false; + mElement = NULL; +} + +void Type::updateFromNative() { + // We have 6 integer to obtain mDimX; mDimY; mDimZ; + // mDimLOD; mDimFaces; mElement; + + /* + int[] dataBuffer = new int[6]; + mRS.nTypeGetNativeData(getID(), dataBuffer); + + mDimX = dataBuffer[0]; + mDimY = dataBuffer[1]; + mDimZ = dataBuffer[2]; + mDimMipmaps = dataBuffer[3] == 1 ? true : false; + mDimFaces = dataBuffer[4] == 1 ? true : false; + + int elementID = dataBuffer[5]; + if(elementID != 0) { + mElement = new Element(elementID, mRS); + mElement.updateFromNative(); + } + calcElementCount(); + */ +} + +Type::Builder::Builder(RenderScript *rs, const Element *e) { + mRS = rs; + mElement = e; + mDimX = 0; + mDimY = 0; + mDimZ = 0; + mDimMipmaps = false; + mDimFaces = false; +} + +void Type::Builder::setX(uint32_t value) { + if(value < 1) { + ALOGE("Values of less than 1 for Dimension X are not valid."); + } + mDimX = value; +} + +void Type::Builder::setY(int value) { + if(value < 1) { + ALOGE("Values of less than 1 for Dimension Y are not valid."); + } + mDimY = value; +} + +void Type::Builder::setMipmaps(bool value) { + mDimMipmaps = value; +} + +void Type::Builder::setFaces(bool value) { + mDimFaces = value; +} + +const Type * Type::Builder::create() { + if (mDimZ > 0) { + if ((mDimX < 1) || (mDimY < 1)) { + ALOGE("Both X and Y dimension required when Z is present."); + } + if (mDimFaces) { + ALOGE("Cube maps not supported with 3D types."); + } + } + if (mDimY > 0) { + if (mDimX < 1) { + ALOGE("X dimension required when Y is present."); + } + } + if (mDimFaces) { + if (mDimY < 1) { + ALOGE("Cube maps require 2D Types."); + } + } + + void * id = rsTypeCreate(mRS->mContext, mElement->getID(), mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces); + Type *t = new Type(id, mRS); + t->mElement = mElement; + t->mDimX = mDimX; + t->mDimY = mDimY; + t->mDimZ = mDimZ; + t->mDimMipmaps = mDimMipmaps; + t->mDimFaces = mDimFaces; + + t->calcElementCount(); + return t; +} + diff --git a/libs/rs/Type.h b/libs/rs/Type.h new file mode 100644 index 0000000..53481c3 --- /dev/null +++ b/libs/rs/Type.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __ANDROID_TYPE_H__ +#define __ANDROID_TYPE_H__ + +#include <rs.h> +#include "RenderScript.h" +#include "Element.h" + +class Type : public BaseObj { +protected: + friend class Allocation; + + uint32_t mDimX; + uint32_t mDimY; + uint32_t mDimZ; + bool mDimMipmaps; + bool mDimFaces; + size_t mElementCount; + const Element *mElement; + + void calcElementCount(); + virtual void updateFromNative(); + +public: + + const Element* getElement() const { + return mElement; + } + + uint32_t getX() const { + return mDimX; + } + + uint32_t getY() const { + return mDimY; + } + + uint32_t getZ() const { + return mDimZ; + } + + bool hasMipmaps() const { + return mDimMipmaps; + } + + bool hasFaces() const { + return mDimFaces; + } + + size_t getCount() const { + return mElementCount; + } + + size_t getSizeBytes() const { + return mElementCount * mElement->getSizeBytes(); + } + + + Type(void *id, RenderScript *rs); + + + class Builder { + protected: + RenderScript *mRS; + uint32_t mDimX; + uint32_t mDimY; + uint32_t mDimZ; + bool mDimMipmaps; + bool mDimFaces; + const Element *mElement; + + public: + Builder(RenderScript *rs, const Element *e); + + void setX(uint32_t value); + void setY(int value); + void setMipmaps(bool value); + void setFaces(bool value); + const Type * create(); + }; + +}; + +#endif diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp index ea92192..fb93d82 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -23,6 +23,11 @@ #include "rsAllocation.h" +#include "system/window.h" +#include "hardware/gralloc.h" +#include "ui/Rect.h" +#include "ui/GraphicBufferMapper.h" + #include <GLES/gl.h> #include <GLES2/gl2.h> #include <GLES/glext.h> @@ -220,7 +225,8 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { } void * ptr = alloc->mHal.state.usrPtr; - if (!ptr) { + if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) { + } else { ptr = malloc(alloc->mHal.state.type->getSizeBytes()); if (!ptr) { free(drv); @@ -248,7 +254,7 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { alloc->mHal.drvState.mallocPtr = ptr; drv->mallocPtr = (uint8_t *)ptr; alloc->mHal.drv = drv; - if (forceZero) { + if (forceZero && ptr) { memset(ptr, 0, alloc->mHal.state.type->getSizeBytes()); } @@ -386,9 +392,96 @@ int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *al return drv->textureID; } +static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer."); + return false; + } + + // This lock is implicitly released by the queue buffer in IoSend + r = nw->lockBuffer(nw, drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer."); + return false; + } + + // Must lock the whole surface + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height); + + void *dst = NULL; + mapper.lock(drv->wndBuffer->handle, + GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN, + bounds, &dst); + alloc->mHal.drvState.mallocPtr = dst; + return true; +} + +void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + + //ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw); + + // Cleanup old surface if there is one. + if (alloc->mHal.state.wndSurface) { + ANativeWindow *old = alloc->mHal.state.wndSurface; + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + mapper.unlock(drv->wndBuffer->handle); + old->queueBuffer(old, drv->wndBuffer); + } + + if (nw != NULL) { + int32_t r; + r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY | + GRALLOC_USAGE_SW_WRITE_OFTEN); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage."); + return; + } + + r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX, + alloc->mHal.state.dimensionY); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions."); + return; + } + + r = native_window_set_buffer_count(nw, 3); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count."); + return; + } + + IoGetBuffer(rsc, alloc, nw); + } +} + +void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) { + DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; + ANativeWindow *nw = alloc->mHal.state.wndSurface; + + GraphicBufferMapper &mapper = GraphicBufferMapper::get(); + mapper.unlock(drv->wndBuffer->handle); + int32_t r = nw->queueBuffer(nw, drv->wndBuffer); + if (r) { + rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer."); + return; + } + + IoGetBuffer(rsc, alloc, nw); +} + +void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) { + ALOGE("not implemented"); +} + + void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t lod, uint32_t count, - const void *data, uint32_t sizeBytes) { + const void *data, size_t sizeBytes) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; const uint32_t eSize = alloc->mHal.state.type->getElementSizeBytes(); @@ -407,7 +500,7 @@ void rsdAllocationData1D(const Context *rsc, const Allocation *alloc, void rsdAllocationData2D(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, - uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) { + uint32_t w, uint32_t h, const void *data, size_t sizeBytes) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; uint32_t eSize = alloc->mHal.state.elementSizeBytes; diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h index 230804b..e3a5126 100644 --- a/libs/rs/driver/rsdAllocation.h +++ b/libs/rs/driver/rsdAllocation.h @@ -24,6 +24,7 @@ #include <GLES2/gl2.h> class RsdFrameBufferObj; +struct ANativeWindowBuffer; struct DrvAllocation { // Is this a legal structure to be used as a texture source. @@ -47,6 +48,7 @@ struct DrvAllocation { bool uploadDeferred; RsdFrameBufferObj * readBackFBO; + ANativeWindowBuffer *wndBuffer; }; GLenum rsdTypeToGLType(RsDataType t); @@ -69,6 +71,12 @@ void rsdAllocationMarkDirty(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc); int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc); +void rsdAllocationSetSurfaceTexture(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc, ANativeWindow *nw); +void rsdAllocationIoSend(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); +void rsdAllocationIoReceive(const android::renderscript::Context *rsc, + android::renderscript::Allocation *alloc); void rsdAllocationData1D(const android::renderscript::Context *rsc, const android::renderscript::Allocation *alloc, diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp index bec6fff..dd78684 100644 --- a/libs/rs/driver/rsdBcc.cpp +++ b/libs/rs/driver/rsdBcc.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include "rsdCore.h" #include "rsdBcc.h" #include "rsdRuntime.h" @@ -30,7 +29,6 @@ extern "C" { #include "libdex/ZipArchive.h" } - using namespace android; using namespace android::renderscript; @@ -45,6 +43,7 @@ struct DrvScript { bcinfo::MetadataExtractor *ME; InvokeFunc_t *mInvokeFunctions; + ForEachFunc_t *mForEachFunctions; void ** mFieldAddress; bool * mFieldIsObject; const uint32_t *mExportForEachSignatureList; @@ -162,8 +161,16 @@ bool rsdScriptInit(const Context *rsc, } exportForEachSignatureCount = drv->ME->getExportForEachSignatureCount(); - rsAssert(exportForEachSignatureCount <= 1); drv->mExportForEachSignatureList = drv->ME->getExportForEachSignatureList(); + if (exportForEachSignatureCount > 0) { + drv->mForEachFunctions = + (ForEachFunc_t*) calloc(exportForEachSignatureCount, + sizeof(ForEachFunc_t)); + bccGetExportForEachList(drv->mBccScript, exportForEachSignatureCount, + (void **) drv->mForEachFunctions); + } else { + drv->mForEachFunctions = NULL; + } // Copy info over to runtime script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount(); @@ -196,6 +203,7 @@ error: typedef struct { Context *rsc; Script *script; + ForEachFunc_t kernel; uint32_t sig; const Allocation * ain; Allocation * aout; @@ -235,7 +243,7 @@ static void wc_xy(void *usr, uint32_t idx) { RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv; uint32_t sig = mtls->sig; - outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root; + outer_foreach_t fn = (outer_foreach_t) mtls->kernel; while (1) { uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum); uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize; @@ -265,7 +273,7 @@ static void wc_x(void *usr, uint32_t idx) { RsdHal * dc = (RsdHal *)mtls->rsc->mHal.drv; uint32_t sig = mtls->sig; - outer_foreach_t fn = (outer_foreach_t) mtls->script->mHal.info.root; + outer_foreach_t fn = (outer_foreach_t) mtls->kernel; while (1) { uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum); uint32_t xStart = mtls->xStart + slice * mtls->mSliceSize; @@ -299,8 +307,8 @@ void rsdScriptInvokeForEach(const Context *rsc, memset(&mtls, 0, sizeof(mtls)); DrvScript *drv = (DrvScript *)s->mHal.drv; - // We only support slot 0 (root) at this point in time. - rsAssert(slot == 0); + mtls.kernel = drv->mForEachFunctions[slot]; + rsAssert(mtls.kernel != NULL); mtls.sig = 0x1f; // temp fix for old apps, full table in slang_rs_export_foreach.cpp if (drv->mExportForEachSignatureList) { mtls.sig = drv->mExportForEachSignatureList[slot]; @@ -391,7 +399,7 @@ void rsdScriptInvokeForEach(const Context *rsc, uint32_t sig = mtls.sig; //ALOGE("launch 3"); - outer_foreach_t fn = (outer_foreach_t) mtls.script->mHal.info.root; + outer_foreach_t fn = (outer_foreach_t) mtls.kernel; 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++) { @@ -517,6 +525,11 @@ void rsdScriptDestroy(const Context *dc, Script *script) { drv->mInvokeFunctions = NULL; } + if (drv->mForEachFunctions) { + free(drv->mForEachFunctions); + drv->mForEachFunctions = NULL; + } + delete drv->ME; drv->ME = NULL; diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp index e011955..bf2b62a 100644 --- a/libs/rs/driver/rsdCore.cpp +++ b/libs/rs/driver/rsdCore.cpp @@ -74,6 +74,9 @@ static RsdHalFunctions FunctionTable = { rsdAllocationSyncAll, rsdAllocationMarkDirty, rsdAllocationInitSurfaceTexture, + rsdAllocationSetSurfaceTexture, + rsdAllocationIoSend, + rsdAllocationIoReceive, rsdAllocationData1D, rsdAllocationData2D, rsdAllocationData3D, diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h index 168bdf3..05ca13bb 100644 --- a/libs/rs/driver/rsdCore.h +++ b/libs/rs/driver/rsdCore.h @@ -25,6 +25,7 @@ #include "rsdGL.h" typedef void (* InvokeFunc_t)(void); +typedef void (* ForEachFunc_t)(void); typedef void (*WorkerCallback_t)(void *usr, uint32_t idx); typedef struct RsdSymbolTableRec { diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp index b136cc7..8033b08 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -16,8 +16,8 @@ #include <ui/FramebufferNativeWindow.h> #include <ui/PixelFormat.h> -#include <ui/EGLUtils.h> -#include <ui/egl/android_natives.h> + +#include <system/window.h> #include <sys/types.h> #include <sys/resource.h> @@ -47,6 +47,29 @@ using namespace android::renderscript; static int32_t gGLContextCount = 0; static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + struct EGLUtils { + static const char *strerror(EGLint err) { + switch (err){ + case EGL_SUCCESS: return "EGL_SUCCESS"; + case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; + case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; + case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; + case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; + case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; + case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; + case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; + case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; + default: return "UNKNOWN"; + } + } + }; + if (returnVal != EGL_TRUE) { fprintf(stderr, "%s() returned %d\n", op, returnVal); } diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp index 54484df..fa4cb0f 100644 --- a/libs/rs/driver/rsdProgram.cpp +++ b/libs/rs/driver/rsdProgram.cpp @@ -34,8 +34,11 @@ using namespace android; using namespace android::renderscript; bool rsdProgramVertexInit(const Context *rsc, const ProgramVertex *pv, - const char* shader, uint32_t shaderLen) { - RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { + RsdShader *drv = new RsdShader(pv, GL_VERTEX_SHADER, shader, shaderLen, + textureNames, textureNamesCount, textureNamesLength); pv->mHal.drv = drv; return drv->createShader(); @@ -78,8 +81,11 @@ void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) { } bool rsdProgramFragmentInit(const Context *rsc, const ProgramFragment *pf, - const char* shader, uint32_t shaderLen) { - RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { + RsdShader *drv = new RsdShader(pf, GL_FRAGMENT_SHADER, shader, shaderLen, + textureNames, textureNamesCount, textureNamesLength); pf->mHal.drv = drv; return drv->createShader(); diff --git a/libs/rs/driver/rsdProgramFragment.h b/libs/rs/driver/rsdProgramFragment.h index 366cb40..b03a9fe 100644 --- a/libs/rs/driver/rsdProgramFragment.h +++ b/libs/rs/driver/rsdProgramFragment.h @@ -22,7 +22,9 @@ bool rsdProgramFragmentInit(const android::renderscript::Context *rsc, const android::renderscript::ProgramFragment *, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void rsdProgramFragmentSetActive(const android::renderscript::Context *rsc, const android::renderscript::ProgramFragment *); void rsdProgramFragmentDestroy(const android::renderscript::Context *rsc, diff --git a/libs/rs/driver/rsdProgramVertex.h b/libs/rs/driver/rsdProgramVertex.h index e998572..f917a41 100644 --- a/libs/rs/driver/rsdProgramVertex.h +++ b/libs/rs/driver/rsdProgramVertex.h @@ -21,7 +21,9 @@ bool rsdProgramVertexInit(const android::renderscript::Context *rsc, const android::renderscript::ProgramVertex *, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void rsdProgramVertexSetActive(const android::renderscript::Context *rsc, const android::renderscript::ProgramVertex *); void rsdProgramVertexDestroy(const android::renderscript::Context *rsc, diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp index 3bca794..1e73b95 100644 --- a/libs/rs/driver/rsdShader.cpp +++ b/libs/rs/driver/rsdShader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2011-2012 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. @@ -30,14 +30,16 @@ using namespace android; using namespace android::renderscript; RsdShader::RsdShader(const Program *p, uint32_t type, - const char * shaderText, uint32_t shaderLength) { - + const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { mUserShader.setTo(shaderText, shaderLength); mRSProgram = p; mType = type; initMemberVars(); initAttribAndUniformArray(); - init(); + init(textureNames, textureNamesCount, textureNamesLength); + createTexturesString(textureNames, textureNamesCount, textureNamesLength); } RsdShader::~RsdShader() { @@ -65,25 +67,26 @@ void RsdShader::initMemberVars() { mIsValid = false; } -void RsdShader::init() { +void RsdShader::init(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { uint32_t attribCount = 0; uint32_t uniformCount = 0; for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) { - initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, NULL, &attribCount, RS_SHADER_ATTR); + initAddUserElement(mRSProgram->mHal.state.inputElements[ct], mAttribNames, + NULL, &attribCount, RS_SHADER_ATTR); } for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) { - initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI); + initAddUserElement(mRSProgram->mHal.state.constantTypes[ct]->getElement(), + mUniformNames, mUniformArraySizes, &uniformCount, RS_SHADER_UNI); } mTextureUniformIndexStart = uniformCount; - char buf[256]; for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) { - snprintf(buf, sizeof(buf), "UNI_Tex%i", ct); - mUniformNames[uniformCount].setTo(buf); + mUniformNames[uniformCount].setTo("UNI_"); + mUniformNames[uniformCount].append(textureNames[ct], textureNamesLength[ct]); mUniformArraySizes[uniformCount] = 1; uniformCount++; } - } String8 RsdShader::getGLSLInputString() const { @@ -135,22 +138,25 @@ void RsdShader::appendAttributes() { } } -void RsdShader::appendTextures() { - char buf[256]; - for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) { +void RsdShader::createTexturesString(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength) { + mShaderTextures.setTo(""); + for (uint32_t ct = 0; ct < mRSProgram->mHal.state.texturesCount; ct ++) { if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) { Allocation *a = mRSProgram->mHal.state.textures[ct]; if (a && a->mHal.state.surfaceTextureID) { - snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct); + mShaderTextures.append("uniform samplerExternalOES UNI_"); } else { - snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct); + mShaderTextures.append("uniform sampler2D UNI_"); } mTextureTargets[ct] = GL_TEXTURE_2D; } else { - snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct); + mShaderTextures.append("uniform samplerCube UNI_"); mTextureTargets[ct] = GL_TEXTURE_CUBE_MAP; } - mShader.append(buf); + + mShaderTextures.append(textureNames[ct], textureNamesLength[ct]); + mShaderTextures.append(";\n"); } } @@ -161,7 +167,7 @@ bool RsdShader::createShader() { } appendUserConstants(); appendAttributes(); - appendTextures(); + mShader.append(mShaderTextures); mShader.append(mUserShader); @@ -418,7 +424,8 @@ void RsdShader::setupTextures(const Context *rsc, RsdShaderCache *sc) { DrvAllocation *drvTex = (DrvAllocation *)mRSProgram->mHal.state.textures[ct]->mHal.drv; if (drvTex->glTarget != GL_TEXTURE_2D && drvTex->glTarget != GL_TEXTURE_CUBE_MAP) { - ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct); + ALOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", + (uint)this, ct); rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader"); } RSD_CALL_GL(glBindTexture, drvTex->glTarget, drvTex->textureID); diff --git a/libs/rs/driver/rsdShader.h b/libs/rs/driver/rsdShader.h index 3f0d6ea..e32145f 100644 --- a/libs/rs/driver/rsdShader.h +++ b/libs/rs/driver/rsdShader.h @@ -39,7 +39,9 @@ class RsdShader { public: RsdShader(const android::renderscript::Program *p, uint32_t type, - const char * shaderText, uint32_t shaderLength); + const char * shaderText, uint32_t shaderLength, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); virtual ~RsdShader(); bool createShader(); @@ -67,19 +69,27 @@ protected: // Applies to vertex and fragment shaders only void appendUserConstants(); - void setupUserConstants(const android::renderscript::Context *rsc, RsdShaderCache *sc, bool isFragment); - void initAddUserElement(const android::renderscript::Element *e, android::String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix); + void setupUserConstants(const android::renderscript::Context *rsc, + RsdShaderCache *sc, bool isFragment); + void initAddUserElement(const android::renderscript::Element *e, + android::String8 *names, uint32_t *arrayLengths, + uint32_t *count, const char *prefix); void setupTextures(const android::renderscript::Context *rsc, RsdShaderCache *sc); - void setupSampler(const android::renderscript::Context *rsc, const android::renderscript::Sampler *s, const android::renderscript::Allocation *tex); + void setupSampler(const android::renderscript::Context *rsc, + const android::renderscript::Sampler *s, + const android::renderscript::Allocation *tex); void appendAttributes(); void appendTextures(); + void createTexturesString(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void initAttribAndUniformArray(); mutable bool mDirty; android::String8 mShader; android::String8 mUserShader; + android::String8 mShaderTextures; uint32_t mShaderID; uint32_t mType; @@ -93,10 +103,14 @@ protected: int32_t mTextureUniformIndexStart; - void logUniform(const android::renderscript::Element *field, const float *fd, uint32_t arraySize ); - void setUniform(const android::renderscript::Context *rsc, const android::renderscript::Element *field, const float *fd, int32_t slot, uint32_t arraySize ); + void logUniform(const android::renderscript::Element *field, + const float *fd, uint32_t arraySize); + void setUniform(const android::renderscript::Context *rsc, + const android::renderscript::Element *field, + const float *fd, int32_t slot, uint32_t arraySize ); void initMemberVars(); - void init(); + void init(const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); }; #endif //ANDROID_RSD_SHADER_H diff --git a/libs/rs/rs.h b/libs/rs/rs.h new file mode 100644 index 0000000..fbcaf4a --- /dev/null +++ b/libs/rs/rs.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RENDER_SCRIPT_H +#define RENDER_SCRIPT_H + +#include <stdint.h> +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#include "rsDefines.h" + +// +// A3D loading and object update code. +// Should only be called at object creation, not thread safe +RsObjectBase rsaFileA3DGetEntryByIndex(RsContext, uint32_t idx, RsFile); +RsFile rsaFileA3DCreateFromMemory(RsContext, const void *data, uint32_t len); +RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset); +RsFile rsaFileA3DCreateFromFile(RsContext, const char *path); +void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile); +void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries, + uint32_t numEntries, RsFile); +void rsaGetName(RsContext, void * obj, const char **name); +// Mesh update functions +void rsaMeshGetVertexBufferCount(RsContext, RsMesh, int32_t *vtxCount); +void rsaMeshGetIndexCount(RsContext, RsMesh, int32_t *idxCount); +void rsaMeshGetVertices(RsContext, RsMesh, RsAllocation *vtxData, uint32_t vtxDataCount); +void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va, + uint32_t *primType, uint32_t idxDataCount); +// Allocation update +const void* rsaAllocationGetType(RsContext con, RsAllocation va); +// Type update +void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize); +// Element update +void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize); +void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, + uint32_t *arraySizes, uint32_t dataSize); + +RsDevice rsDeviceCreate(); +void rsDeviceDestroy(RsDevice dev); +void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value); +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" + +#ifdef __cplusplus +}; +#endif + +#endif // RENDER_SCRIPT_H + + + diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index 6759bc7..cf4a391 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -69,168 +69,183 @@ AllocationGetSurfaceTextureID { ret int32_t } +AllocationSetSurface { + param RsAllocation alloc + param RsNativeWindow sur + sync + } + +AllocationIoSend { + param RsAllocation alloc + } + +AllocationIoReceive { + param RsAllocation alloc + } + + ContextFinish { - sync - } + sync + } ContextBindRootScript { - param RsScript sampler - } + param RsScript sampler + } ContextBindProgramStore { - param RsProgramStore pgm - } + param RsProgramStore pgm + } ContextBindProgramFragment { - param RsProgramFragment pgm - } + param RsProgramFragment pgm + } ContextBindProgramVertex { - param RsProgramVertex pgm - } + param RsProgramVertex pgm + } ContextBindProgramRaster { - param RsProgramRaster pgm - } + param RsProgramRaster pgm + } ContextBindFont { - param RsFont pgm - } + param RsFont pgm + } ContextPause { - } + } ContextResume { - } + } ContextSetSurface { - param uint32_t width - param uint32_t height - param RsNativeWindow sur + param uint32_t width + param uint32_t height + param RsNativeWindow sur sync - } + } ContextDump { - param int32_t bits + param int32_t bits } ContextSetPriority { - param int32_t priority - } + param int32_t priority + } ContextDestroyWorker { sync } AssignName { - param RsObjectBase obj - param const char *name - } + param RsObjectBase obj + param const char *name + } ObjDestroy { - param RsAsyncVoidPtr objPtr - } + param RsAsyncVoidPtr objPtr + } ElementCreate { direct - param RsDataType mType - param RsDataKind mKind - param bool mNormalized - param uint32_t mVectorSize - ret RsElement - } + param RsDataType mType + param RsDataKind mKind + param bool mNormalized + param uint32_t mVectorSize + ret RsElement + } ElementCreate2 { direct - param const RsElement * elements - param const char ** names - param const uint32_t * arraySize - ret RsElement - } + param const RsElement * elements + param const char ** names + param const uint32_t * arraySize + ret RsElement + } AllocationCopyToBitmap { - param RsAllocation alloc - param void * data - } + param RsAllocation alloc + param void * data + } Allocation1DData { - param RsAllocation va - param uint32_t xoff - param uint32_t lod - param uint32_t count - param const void *data - } + param RsAllocation va + param uint32_t xoff + param uint32_t lod + param uint32_t count + param const void *data + } Allocation1DElementData { - param RsAllocation va - param uint32_t x - param uint32_t lod - param const void *data - param size_t comp_offset - } + param RsAllocation va + param uint32_t x + param uint32_t lod + param const void *data + param size_t comp_offset + } Allocation2DData { - param RsAllocation va - param uint32_t xoff - param uint32_t yoff - param uint32_t lod - param RsAllocationCubemapFace face - param uint32_t w - param uint32_t h - param const void *data - } + param RsAllocation va + param uint32_t xoff + param uint32_t yoff + param uint32_t lod + param RsAllocationCubemapFace face + param uint32_t w + param uint32_t h + param const void *data + } Allocation2DElementData { - param RsAllocation va - param uint32_t x - param uint32_t y - param uint32_t lod - param RsAllocationCubemapFace face - param const void *data - param size_t element_offset - } + param RsAllocation va + param uint32_t x + param uint32_t y + param uint32_t lod + param RsAllocationCubemapFace face + param const void *data + param size_t element_offset + } AllocationGenerateMipmaps { - param RsAllocation va + param RsAllocation va } AllocationRead { - param RsAllocation va - param void * data - } + param RsAllocation va + param void * data + } AllocationSyncAll { - param RsAllocation va - param RsAllocationUsageType src + param RsAllocation va + param RsAllocationUsageType src } AllocationResize1D { - param RsAllocation va - param uint32_t dimX - } + param RsAllocation va + param uint32_t dimX + } AllocationResize2D { - param RsAllocation va - param uint32_t dimX - param uint32_t dimY - } + param RsAllocation va + param uint32_t dimX + param uint32_t dimY + } AllocationCopy2DRange { - param RsAllocation dest - param uint32_t destXoff - param uint32_t destYoff - param uint32_t destMip - param uint32_t destFace - param uint32_t width - param uint32_t height - param RsAllocation src - param uint32_t srcXoff - param uint32_t srcYoff - param uint32_t srcMip - param uint32_t srcFace - } + param RsAllocation dest + param uint32_t destXoff + param uint32_t destYoff + param uint32_t destMip + param uint32_t destFace + param uint32_t width + param uint32_t height + param RsAllocation src + param uint32_t srcXoff + param uint32_t srcYoff + param uint32_t srcMip + param uint32_t srcFace + } SamplerCreate { direct @@ -244,26 +259,26 @@ SamplerCreate { } ScriptBindAllocation { - param RsScript vtm - param RsAllocation va - param uint32_t slot - } + param RsScript vtm + param RsAllocation va + param uint32_t slot + } ScriptSetTimeZone { - param RsScript s - param const char * timeZone - } + param RsScript s + param const char * timeZone + } ScriptInvoke { - param RsScript s - param uint32_t slot - } + param RsScript s + param uint32_t slot + } ScriptInvokeV { - param RsScript s - param uint32_t slot - param const void * data - } + param RsScript s + param uint32_t slot + param const void * data + } ScriptForEach { param RsScript s @@ -274,125 +289,127 @@ ScriptForEach { } ScriptSetVarI { - param RsScript s - param uint32_t slot - param int value - } + param RsScript s + param uint32_t slot + param int value + } ScriptSetVarObj { - param RsScript s - param uint32_t slot - param RsObjectBase value - } + param RsScript s + param uint32_t slot + param RsObjectBase value + } ScriptSetVarJ { - param RsScript s - param uint32_t slot - param int64_t value - } + param RsScript s + param uint32_t slot + param int64_t value + } ScriptSetVarF { - param RsScript s - param uint32_t slot - param float value - } + param RsScript s + param uint32_t slot + param float value + } ScriptSetVarD { - param RsScript s - param uint32_t slot - param double value - } + param RsScript s + param uint32_t slot + param double value + } ScriptSetVarV { - param RsScript s - param uint32_t slot - param const void * data - } + param RsScript s + param uint32_t slot + param const void * data + } ScriptCCreate { param const char * resName param const char * cacheDir - param const char * text - ret RsScript - } + param const char * text + ret RsScript + } ProgramStoreCreate { - direct - param bool colorMaskR - param bool colorMaskG - param bool colorMaskB - param bool colorMaskA + direct + param bool colorMaskR + param bool colorMaskG + param bool colorMaskB + param bool colorMaskA param bool depthMask param bool ditherEnable - param RsBlendSrcFunc srcFunc - param RsBlendDstFunc destFunc + param RsBlendSrcFunc srcFunc + param RsBlendDstFunc destFunc param RsDepthFunc depthFunc - ret RsProgramStore - } + ret RsProgramStore + } ProgramRasterCreate { - direct - param bool pointSprite - param RsCullMode cull - ret RsProgramRaster + direct + param bool pointSprite + param RsCullMode cull + ret RsProgramRaster } ProgramBindConstants { - param RsProgram vp - param uint32_t slot - param RsAllocation constants - } + param RsProgram vp + param uint32_t slot + param RsAllocation constants + } ProgramBindTexture { - param RsProgramFragment pf - param uint32_t slot - param RsAllocation a - } + param RsProgramFragment pf + param uint32_t slot + param RsAllocation a + } ProgramBindSampler { - param RsProgramFragment pf - param uint32_t slot - param RsSampler s - } + param RsProgramFragment pf + param uint32_t slot + param RsSampler s + } ProgramFragmentCreate { - direct - param const char * shaderText - param const uint32_t * params - ret RsProgramFragment - } + direct + param const char * shaderText + param const char ** textureNames + param const uint32_t * params + ret RsProgramFragment + } ProgramVertexCreate { - direct - param const char * shaderText - param const uint32_t * params - ret RsProgramVertex - } + direct + param const char * shaderText + param const char ** textureNames + param const uint32_t * params + ret RsProgramVertex + } FontCreateFromFile { - param const char *name - param float fontSize - param uint32_t dpi - ret RsFont - } + param const char *name + param float fontSize + param uint32_t dpi + ret RsFont + } FontCreateFromMemory { - param const char *name - param float fontSize - param uint32_t dpi - param const void *data - ret RsFont - } + param const char *name + param float fontSize + param uint32_t dpi + param const void *data + ret RsFont + } MeshCreate { - param RsAllocation *vtx - param RsAllocation *idx - param uint32_t *primType - ret RsMesh - } + param RsAllocation *vtx + param RsAllocation *idx + param uint32_t *primType + ret RsMesh + } PathCreate { param RsPathPrimitive pp @@ -402,4 +419,3 @@ PathCreate { param float quality ret RsPath } - diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp index 02c6809..83c88fd 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -17,6 +17,7 @@ #include "rsContext.h" #include "rs_hal.h" +#include "system/window.h" using namespace android; using namespace android::renderscript; @@ -44,6 +45,7 @@ Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32 delete a; return NULL; } + return a; } @@ -420,6 +422,28 @@ int32_t Allocation::getSurfaceTextureID(const Context *rsc) { return id; } +void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) { + ANativeWindow *nw = (ANativeWindow *)sur; + ANativeWindow *old = mHal.state.wndSurface; + if (nw) { + nw->incStrong(NULL); + } + rsc->mHal.funcs.allocation.setSurfaceTexture(rsc, this, nw); + mHal.state.wndSurface = nw; + if (old) { + old->decStrong(NULL); + } +} + +void Allocation::ioSend(const Context *rsc) { + rsc->mHal.funcs.allocation.ioSend(rsc, this); +} + +void Allocation::ioReceive(const Context *rsc) { + rsc->mHal.funcs.allocation.ioReceive(rsc, this); +} + + ///////////////// // @@ -670,6 +694,21 @@ int32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) { return alloc->getSurfaceTextureID(rsc); } +void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->setSurface(rsc, sur); +} + +void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->ioSend(rsc); +} + +void rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { + Allocation *alloc = static_cast<Allocation *>(valloc); + alloc->ioReceive(rsc); +} + } } diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index 58a582b..58a6fca 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -19,6 +19,8 @@ #include "rsType.h" +struct ANativeWindow; + // --------------------------------------------------------------------------- namespace android { namespace renderscript { @@ -57,6 +59,7 @@ public: bool hasReferences; void * usrPtr; int32_t surfaceTextureID; + ANativeWindow *wndSurface; }; State state; @@ -127,6 +130,9 @@ public: } int32_t getSurfaceTextureID(const Context *rsc); + void setSurface(const Context *rsc, RsNativeWindow sur); + void ioSend(const Context *rsc); + void ioReceive(const Context *rsc); protected: Vector<const Program *> mToDirtyList; diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index adaefc6..95ac76e 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -263,6 +263,10 @@ void * Context::threadProc(void *vrsc) { rsc->timerSet(RS_TIMER_IDLE); #ifndef ANDROID_RS_SERIALIZE + if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) { + targetRate = 0; + } + if (vsyncRate != targetRate) { displayEvent.setVsyncRate(targetRate); vsyncRate = targetRate; diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/rsDefines.h index 990ef26..990ef26 100644 --- a/libs/rs/RenderScriptDefines.h +++ b/libs/rs/rsDefines.h diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/rsEnv.h index b82eaf1..b82eaf1 100644 --- a/libs/rs/RenderScriptEnv.h +++ b/libs/rs/rsEnv.h diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h index 056b5af..baf81de 100644 --- a/libs/rs/rsFileA3D.h +++ b/libs/rs/rsFileA3D.h @@ -17,11 +17,11 @@ #ifndef ANDROID_RS_FILE_A3D_H #define ANDROID_RS_FILE_A3D_H -#include "RenderScript.h" +#include "rs.h" #include "rsMesh.h" +#include <androidfw/Asset.h> #include <utils/String8.h> -#include <utils/Asset.h> #include "rsStream.h" #include <stdio.h> diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 4f21b3b..c4276cf 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -490,8 +490,14 @@ void FontState::initRenderState() { shaderString.append(" gl_FragColor = col;\n"); shaderString.append("}\n"); - 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); + const char *textureNames[] = { "Tex0" }; + const size_t textureNamesLengths[] = { 4 }; + size_t numTextures = sizeof(textureNamesLengths)/sizeof(*textureNamesLengths); + + 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); @@ -506,14 +512,17 @@ void FontState::initRenderState() { tmp[3] = RS_TEXTURE_2D; 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); + RS_ALLOCATION_USAGE_SCRIPT | + RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS)); + ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), shaderString.length(), + textureNames, numTextures, textureNamesLengths, + tmp, 4); mFontShaderF.set(pf); mFontShaderF->bindAllocation(mRSC, mFontShaderFConstant.get(), 0); mFontSampler.set(Sampler::getSampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST, - RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP).get()); + 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, @@ -525,10 +534,12 @@ void FontState::initRenderState() { } void FontState::initTextTexture() { - ObjectBaseRef<const Element> alphaElem = Element::createRef(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 - ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), 1024, 256, 0, false, false); + ObjectBaseRef<Type> texType = Type::getTypeRef(mRSC, alphaElem.get(), + 1024, 256, 0, false, false); Allocation *cacheAlloc = Allocation::createAllocation(mRSC, texType.get(), RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE); diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h index 4ca794d..88c4795 100644 --- a/libs/rs/rsFont.h +++ b/libs/rs/rsFont.h @@ -17,7 +17,7 @@ #ifndef ANDROID_RS_FONT_H #define ANDROID_RS_FONT_H -#include "RenderScript.h" +#include "rs.h" #include "rsStream.h" #include <utils/String8.h> #include <utils/Vector.h> diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h index 166b5d3..8eea427 100644 --- a/libs/rs/rsMesh.h +++ b/libs/rs/rsMesh.h @@ -18,7 +18,7 @@ #define ANDROID_RS_MESH_H -#include "RenderScript.h" +#include "rs.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h index dac795e..7c05503 100644 --- a/libs/rs/rsPath.h +++ b/libs/rs/rsPath.h @@ -18,7 +18,7 @@ #define ANDROID_RS_PATH_H -#include "RenderScript.h" +#include "rs.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 8061515..7114f29 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -20,8 +20,8 @@ using namespace android; using namespace android::renderscript; -Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, - const uint32_t * params, uint32_t paramLength) +Program::Program(Context *rsc, const char * shaderText, size_t shaderLength, + const uint32_t * params, size_t paramLength) : ProgramBase(rsc) { initMemberVars(); diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index 06fc3ec..d032930 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -58,8 +58,8 @@ public: }; Hal mHal; - Program(Context *, const char * shaderText, uint32_t shaderLength, - const uint32_t * params, uint32_t paramLength); + Program(Context *, const char * shaderText, size_t shaderLength, + const uint32_t * params, size_t paramLength); virtual ~Program(); virtual bool freeChildren(); diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 4e73ca6..bebde1e 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -20,16 +20,18 @@ using namespace android; using namespace android::renderscript; -ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, - uint32_t shaderLength, const uint32_t * params, - uint32_t paramLength) +ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + + const uint32_t * params, size_t paramLength) : Program(rsc, shaderText, shaderLength, params, paramLength) { mConstantColor[0] = 1.f; mConstantColor[1] = 1.f; mConstantColor[2] = 1.f; mConstantColor[3] = 1.f; - mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length()); + mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length(), + textureNames, textureNamesCount, textureNamesLength); } ProgramFragment::~ProgramFragment() { @@ -110,8 +112,8 @@ void ProgramFragmentState::init(Context *rsc) { 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); + ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), shaderString.length(), + NULL, 0, NULL, tmp, 2); pf->bindAllocation(rsc, constAlloc, 0); pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f); @@ -127,9 +129,14 @@ namespace android { namespace renderscript { RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText, - size_t shaderLength, const uint32_t * params, - size_t paramLength) { - ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength); + size_t shaderLength, + const char** textureNames, + size_t textureNamesCount, + const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength) { + ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, + textureNames, textureNamesCount, textureNamesLength, + params, paramLength); pf->incUserRef(); //ALOGE("rsi_ProgramFragmentCreate %p", pf); return pf; diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h index d6e20cd..4eb28e7 100644 --- a/libs/rs/rsProgramFragment.h +++ b/libs/rs/rsProgramFragment.h @@ -27,9 +27,9 @@ class ProgramFragmentState; class ProgramFragment : public Program { public: - ProgramFragment(Context *rsc, const char * shaderText, - uint32_t shaderLength, const uint32_t * params, - uint32_t paramLength); + ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength); virtual ~ProgramFragment(); virtual void setup(Context *, ProgramFragmentState *); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 871caac..c8a53ea 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -21,11 +21,13 @@ using namespace android; using namespace android::renderscript; -ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, - uint32_t shaderLength, const uint32_t * params, - uint32_t paramLength) +ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + + const uint32_t * params, size_t paramLength) : Program(rsc, shaderText, shaderLength, params, paramLength) { - mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length()); + mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader.string(), mUserShader.length(), + textureNames, textureNamesCount, textureNamesLength); } ProgramVertex::~ProgramVertex() { @@ -191,8 +193,8 @@ void ProgramVertexState::init(Context *rsc) { tmp[2] = RS_PROGRAM_PARAM_INPUT; tmp[3] = (uint32_t)attrElem.get(); - ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), - shaderString.length(), tmp, 4); + ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), shaderString.length(), + NULL, 0, NULL, tmp, 4); Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(), RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS); pv->bindAllocation(rsc, alloc, 0); @@ -229,10 +231,13 @@ void ProgramVertexState::deinit(Context *rsc) { namespace android { namespace renderscript { -RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, - size_t shaderLength, const uint32_t * params, - size_t paramLength) { - ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, params, paramLength); +RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength) { + ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength, + textureNames, textureNamesCount, textureNamesLength, + params, paramLength); pv->incUserRef(); return pv; } diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h index 5cfdd8b..67c2a88 100644 --- a/libs/rs/rsProgramVertex.h +++ b/libs/rs/rsProgramVertex.h @@ -27,8 +27,9 @@ class ProgramVertexState; class ProgramVertex : public Program { public: - ProgramVertex(Context *,const char * shaderText, uint32_t shaderLength, - const uint32_t * params, uint32_t paramLength); + ProgramVertex(Context *,const char * shaderText, size_t shaderLength, + const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength, + const uint32_t * params, size_t paramLength); virtual ~ProgramVertex(); virtual void setup(Context *rsc, ProgramVertexState *state); diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h index 654cd9c..013e4ca 100644 --- a/libs/rs/rsSampler.h +++ b/libs/rs/rsSampler.h @@ -18,7 +18,7 @@ #define ANDROID_RS_SAMPLER_H #include "rsAllocation.h" -#include "RenderScript.h" +#include "rs.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp index 357dbe3..6a3bd4b 100644 --- a/libs/rs/rsScript.cpp +++ b/libs/rs/rsScript.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-2012 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. @@ -113,7 +113,7 @@ void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot, RsAllocation vain, RsAllocation vaout, const void *params, size_t paramLen) { Script *s = static_cast<Script *>(vs); - s->runForEach(rsc, + s->runForEach(rsc, slot, static_cast<const Allocation *>(vain), static_cast<Allocation *>(vaout), params, paramLen); diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h index 99dceaf..7879ea6 100644 --- a/libs/rs/rsScript.h +++ b/libs/rs/rsScript.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-2012 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. @@ -74,6 +74,7 @@ public: virtual bool freeChildren(); virtual void runForEach(Context *rsc, + uint32_t slot, const Allocation * ain, Allocation * aout, const void * usr, diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index b4eb995..79725b9 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-2012 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. @@ -128,6 +128,7 @@ uint32_t ScriptC::run(Context *rsc) { void ScriptC::runForEach(Context *rsc, + uint32_t slot, const Allocation * ain, Allocation * aout, const void * usr, @@ -138,7 +139,7 @@ void ScriptC::runForEach(Context *rsc, setupGLState(rsc); setupScript(rsc); - rsc->mHal.funcs.script.invokeForEach(rsc, this, 0, ain, aout, usr, usrBytes, sc); + rsc->mHal.funcs.script.invokeForEach(rsc, this, slot, ain, aout, usr, usrBytes, sc); } void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len) { diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h index c65a5bf..92e1f4f 100644 --- a/libs/rs/rsScriptC.h +++ b/libs/rs/rsScriptC.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-2012 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. @@ -19,7 +19,7 @@ #include "rsScript.h" -#include "RenderScriptEnv.h" +#include "rsEnv.h" #ifndef ANDROID_RS_SERIALIZE #include "bcinfo/BitcodeTranslator.h" @@ -47,6 +47,7 @@ public: virtual uint32_t run(Context *); virtual void runForEach(Context *rsc, + uint32_t slot, const Allocation * ain, Allocation * aout, const void * usr, diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 183e207..a5a0fae 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2009-2012 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. @@ -157,7 +157,7 @@ void rsrForEach(Context *rsc, Script *sc, Allocation *in, Allocation *out, const void *usr, uint32_t usrBytes, const RsScriptCall *call) { - target->runForEach(rsc, in, out, usr, usrBytes, call); + target->runForEach(rsc, /* root slot */ 0, in, out, usr, usrBytes, call); } void rsrAllocationSyncAll(Context *rsc, Script *sc, Allocation *a, RsAllocationUsageType usage) { diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 4f30573..7182f53 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -31,6 +31,8 @@ using namespace android::renderscript; ThreadIO::ThreadIO() { mRunning = true; + mPureFifo = false; + mMaxInlineSize = 1024; } ThreadIO::~ThreadIO() { @@ -65,6 +67,16 @@ void ThreadIO::clientShutdown() { mToClient.shutdown(); } +void ThreadIO::coreWrite(const void *data, size_t len) { + //ALOGV("core write %p %i", data, (int)len); + mToCore.writeAsync(data, len, true); +} + +void ThreadIO::coreRead(void *data, size_t len) { + //ALOGV("core read %p %i", data, (int)len); + mToCore.read(data, len); +} + void ThreadIO::coreSetReturn(const void *data, size_t dataLen) { uint32_t buf; if (data == NULL) { @@ -91,6 +103,7 @@ void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeou bool ThreadIO::playCoreCommands(Context *con, int waitFd) { bool ret = false; + const bool isLocal = !isPureFifo(); uint8_t buf[2 * 1024]; const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0]; @@ -120,14 +133,19 @@ bool ThreadIO::playCoreCommands(Context *con, int waitFd) { } if (p[0].revents) { - size_t r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); - mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); - - if (r != sizeof(CoreCmdHeader)) { - // exception or timeout occurred. - break; + size_t r = 0; + if (isLocal) { + r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); + mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); + if (r != sizeof(CoreCmdHeader)) { + // exception or timeout occurred. + break; + } + } else { + r = mToCore.read((void *)&cmd->cmdID, sizeof(cmd->cmdID)); } + ret = true; if (con->props.mLogTimes) { con->timerSet(Context::RS_TIMER_INTERNAL); @@ -138,7 +156,12 @@ bool ThreadIO::playCoreCommands(Context *con, int waitFd) { rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID); } - gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); + + if (isLocal) { + gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); + } else { + gPlaybackRemoteFuncs[cmd->cmdID](con, this); + } if (con->props.mLogTimes) { con->timerSet(Context::RS_TIMER_IDLE); diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index 62e3e33..cb7d4ab 100644 --- a/libs/rs/rsThreadIO.h +++ b/libs/rs/rsThreadIO.h @@ -34,6 +34,13 @@ public: void init(); void shutdown(); + size_t getMaxInlineSize() { + return mMaxInlineSize; + } + bool isPureFifo() { + return mPureFifo; + } + // Plays back commands from the client. // Returns true if any commands were processed. bool playCoreCommands(Context *con, int waitFd); @@ -42,8 +49,16 @@ public: void * coreHeader(uint32_t, size_t dataLen); void coreCommit(); + void coreSetReturn(const void *data, size_t dataLen); void coreGetReturn(void *data, size_t dataLen); + void coreWrite(const void *data, size_t len); + void coreRead(void *data, size_t len); + + void asyncSetReturn(const void *data, size_t dataLen); + void asyncGetReturn(void *data, size_t dataLen); + void asyncWrite(const void *data, size_t len); + void asyncRead(void *data, size_t len); RsMessageToClientType getClientHeader(size_t *receiveLen, uint32_t *usrID); @@ -65,6 +80,8 @@ protected: ClientCmdHeader mLastClientHeader; bool mRunning; + bool mPureFifo; + size_t mMaxInlineSize; FifoSocket mToClient; FifoSocket mToCore; diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h index db6f592..a9a992a 100644 --- a/libs/rs/rsUtils.h +++ b/libs/rs/rsUtils.h @@ -34,7 +34,7 @@ #include <math.h> -#include "RenderScript.h" +#include "rs.h" namespace android { namespace renderscript { diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h index 1e222e1..e4bf17f 100644 --- a/libs/rs/rs_hal.h +++ b/libs/rs/rs_hal.h @@ -17,7 +17,9 @@ #ifndef RS_HAL_H #define RS_HAL_H -#include <RenderScriptDefines.h> +#include <rsDefines.h> + +struct ANativeWindow; namespace android { namespace renderscript { @@ -115,19 +117,23 @@ typedef struct { bool zeroNew); void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src); void (*markDirty)(const Context *rsc, const Allocation *alloc); + int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc); + void (*setSurfaceTexture)(const Context *rsc, Allocation *alloc, ANativeWindow *sur); + void (*ioSend)(const Context *rsc, Allocation *alloc); + void (*ioReceive)(const Context *rsc, Allocation *alloc); void (*data1D)(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t lod, uint32_t count, - const void *data, uint32_t sizeBytes); + const void *data, size_t sizeBytes); void (*data2D)(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face, uint32_t w, uint32_t h, - const void *data, uint32_t sizeBytes); + const void *data, size_t sizeBytes); void (*data3D)(const Context *rsc, const Allocation *alloc, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, RsAllocationCubemapFace face, - uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes); + uint32_t w, uint32_t h, uint32_t d, const void *data, size_t sizeBytes); // Allocation to allocation copies void (*allocData1D)(const Context *rsc, @@ -151,9 +157,9 @@ typedef struct { uint32_t srcLod, RsAllocationCubemapFace srcFace); void (*elementData1D)(const Context *rsc, const Allocation *alloc, uint32_t x, - const void *data, uint32_t elementOff, uint32_t sizeBytes); + const void *data, uint32_t elementOff, size_t sizeBytes); void (*elementData2D)(const Context *rsc, const Allocation *alloc, uint32_t x, uint32_t y, - const void *data, uint32_t elementOff, uint32_t sizeBytes); + const void *data, uint32_t elementOff, size_t sizeBytes); } allocation; @@ -172,14 +178,18 @@ typedef struct { struct { bool (*init)(const Context *rsc, const ProgramVertex *pv, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void (*setActive)(const Context *rsc, const ProgramVertex *pv); void (*destroy)(const Context *rsc, const ProgramVertex *pv); } vertex; struct { bool (*init)(const Context *rsc, const ProgramFragment *pf, - const char* shader, uint32_t shaderLen); + const char* shader, size_t shaderLen, + const char** textureNames, size_t textureNamesCount, + const size_t *textureNamesLength); void (*setActive)(const Context *rsc, const ProgramFragment *pf); void (*destroy)(const Context *rsc, const ProgramFragment *pf); } fragment; diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c index 385c8b5..99c305e 100644 --- a/libs/rs/rsg_generator.c +++ b/libs/rs/rsg_generator.c @@ -238,7 +238,7 @@ void printApiCpp(FILE *f) { //fprintf(f, " ALOGE(\"add command %s\\n\");\n", api->name); if (hasInlineDataPointers(api)) { fprintf(f, " RS_CMD_%s *cmd = NULL;\n", api->name); - fprintf(f, " if (dataSize < 1024) {;\n"); + fprintf(f, " if (dataSize < io->getMaxInlineSize()) {;\n"); fprintf(f, " cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name); fprintf(f, " } else {\n"); fprintf(f, " cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name); @@ -252,7 +252,7 @@ void printApiCpp(FILE *f) { const VarType *vt = &api->params[ct2]; needFlush += vt->ptrLevel; if (vt->ptrLevel && hasInlineDataPointers(api)) { - fprintf(f, " if (dataSize < 1024) {\n"); + fprintf(f, " if (dataSize < io->getMaxInlineSize()) {\n"); fprintf(f, " memcpy(payload, %s, %s_length);\n", vt->name, vt->name); fprintf(f, " cmd->%s = (", vt->name); printVarType(f, vt); @@ -272,7 +272,7 @@ void printApiCpp(FILE *f) { fprintf(f, " io->coreCommit();\n"); if (hasInlineDataPointers(api)) { - fprintf(f, " if (dataSize >= 1024) {\n"); + fprintf(f, " if (dataSize >= io->getMaxInlineSize()) {\n"); fprintf(f, " io->coreGetReturn(NULL, 0);\n"); fprintf(f, " }\n"); } else if (api->ret.typeName[0]) { @@ -288,81 +288,71 @@ void printApiCpp(FILE *f) { fprintf(f, "};\n\n"); + // Generate a remote sender function + const char * str = "core"; + if (api->direct) { + str = "async"; + } + fprintf(f, "static "); printFuncDecl(f, api, "RF_", 0, 0); fprintf(f, "\n{\n"); - fprintf(f, " Fifo *f = NULL;\n"); - fprintf(f, " RS_CMD_%s cmd;\n", api->name); - fprintf(f, " const uint32_t cmdSize = sizeof(cmd);\n"); + fprintf(f, " ThreadIO *io = &((Context *)rsc)->mIO;\n"); fprintf(f, " const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name); - fprintf(f, " f->writeAsync(&cmdID, sizeof(cmdID));\n"); - fprintf(f, " intptr_t offset = cmdSize;\n"); - fprintf(f, " uint32_t dataSize = 0;\n"); + fprintf(f, " io->%sWrite(&cmdID, sizeof(cmdID));\n\n", str); + for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - if (vt->isConst && vt->ptrLevel) { - switch(vt->ptrLevel) { - case 1: - fprintf(f, " dataSize += %s_length;\n", vt->name); - break; - case 2: - fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " dataSize += %s_length[ct];\n", vt->name); - fprintf(f, " }\n"); - break; - default: - printf("pointer level not handled!!"); - } + if (vt->ptrLevel == 0) { + fprintf(f, " io->%sWrite(& %s, sizeof(%s));\n", str, vt->name, vt->name); } } fprintf(f, "\n"); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - switch(vt->ptrLevel) { - case 0: - fprintf(f, " cmd.%s = %s;\n", vt->name, vt->name); - break; - case 1: - fprintf(f, " cmd.%s = (", vt->name); - printVarType(f, vt); - fprintf(f, ")offset;\n"); - fprintf(f, " offset += %s_length;\n", vt->name); - break; - case 2: - fprintf(f, " cmd.%s = (", vt->name); - printVarType(f, vt); - fprintf(f, ")offset;\n"); + if ((vt->ptrLevel == 1) && (vt->isConst)) { + fprintf(f, " io->%sWrite(%s, %s_length);\n", str, vt->name, vt->name); + } + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 2) && (vt->isConst)) { fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " offset += %s_length[ct];\n", vt->name); + fprintf(f, " io->%sWrite(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name); fprintf(f, " }\n"); - break; - default: - fprintf(stderr, "pointer level not handled!!"); } } fprintf(f, "\n"); - fprintf(f, " f->writeAsync(&cmd, cmdSize);\n"); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - if (vt->ptrLevel == 1) { - fprintf(f, " f->writeAsync(%s, %s_length);\n", vt->name, vt->name); + if ((vt->ptrLevel == 1) && (!vt->isConst)) { + fprintf(f, " io->%sGetReturn(%s, %s_length);\n", str, vt->name, vt->name); } - if (vt->ptrLevel == 2) { + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 2) && (!vt->isConst)) { fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " f->writeAsync(%s, %s_length[ct]);\n", vt->name, vt->name); - fprintf(f, " offset += %s_length[ct];\n", vt->name); + fprintf(f, " io->%sGetReturn(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name); fprintf(f, " }\n"); } } + fprintf(f, "\n"); if (api->ret.typeName[0]) { fprintf(f, " "); printVarType(f, &api->ret); fprintf(f, " retValue;\n"); - fprintf(f, " f->writeWaitReturn(&retValue, sizeof(retValue));\n"); + fprintf(f, " io->%sGetReturn(&retValue, sizeof(retValue));\n", str); fprintf(f, " return retValue;\n"); + } else /*if (api->sync)*/ { + fprintf(f, " io->%sGetReturn(NULL, 0);\n", str); } fprintf(f, "}\n\n"); } @@ -418,7 +408,6 @@ void printPlaybackCpp(FILE *f) { fprintf(f, "#include \"rsDevice.h\"\n"); fprintf(f, "#include \"rsContext.h\"\n"); fprintf(f, "#include \"rsThreadIO.h\"\n"); - //fprintf(f, "#include \"rsgApiStructs.h\"\n"); fprintf(f, "#include \"rsgApiFuncDecl.h\"\n"); fprintf(f, "\n"); fprintf(f, "namespace android {\n"); @@ -434,8 +423,6 @@ void printPlaybackCpp(FILE *f) { } fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name); - - //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name); fprintf(f, " const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name); if (hasInlineDataPointers(api)) { @@ -488,30 +475,40 @@ void printPlaybackCpp(FILE *f) { const ApiEntry * api = &apis[ct]; int needFlush = 0; - fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name); - - //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name); + fprintf(f, "void rspr_%s(Context *con, ThreadIO *io) {\n", api->name); fprintf(f, " RS_CMD_%s cmd;\n", api->name); - fprintf(f, " f->read(&cmd, sizeof(cmd));\n"); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - needFlush += vt->ptrLevel; + if (vt->ptrLevel == 0) { + fprintf(f, " io->coreRead(&cmd.%s, sizeof(cmd.%s));\n", vt->name, vt->name); + } + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; if (vt->ptrLevel == 1) { fprintf(f, " cmd.%s = (", vt->name); printVarType(f, vt); - fprintf(f, ")scratch;\n"); - fprintf(f, " f->read(scratch, cmd.%s_length);\n", vt->name); - fprintf(f, " scratch += cmd.%s_length;\n", vt->name); + fprintf(f, ")malloc(cmd.%s_length);\n", vt->name); + + if (vt->isConst) { + fprintf(f, " if (cmd.%s_length) io->coreRead((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name, vt->name); + } } + } + fprintf(f, "\n"); + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; if (vt->ptrLevel == 2) { - fprintf(f, " size_t sum_%s = 0;\n", vt->name); fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name); - fprintf(f, " ((size_t *)scratch)[ct] = cmd.%s_length[ct];\n", vt->name); - fprintf(f, " sum_%s += cmd.%s_length[ct];\n", vt->name, vt->name); + fprintf(f, " cmd.%s = (", vt->name); + printVarType(f, vt); + fprintf(f, ")malloc(cmd.%s_length[ct]);\n", vt->name); + fprintf(f, " io->coreRead(& cmd.%s, cmd.%s_length[ct]);\n", vt->name, vt->name); fprintf(f, " }\n"); - fprintf(f, " f->read(scratch, sum_%s);\n", vt->name); - fprintf(f, " scratch += sum_%s;\n", vt->name); } } fprintf(f, "\n"); @@ -535,10 +532,42 @@ void printPlaybackCpp(FILE *f) { } fprintf(f, ");\n"); + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 1) && (!vt->isConst)) { + fprintf(f, " io->coreSetReturn((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name); + } + } + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if ((vt->ptrLevel == 2) && (!vt->isConst)) { + fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name); + fprintf(f, " io->coreSetReturn((void *)cmd.%s[ct], cmd.%s_length[ct]);\n", vt->name, vt->name); + fprintf(f, " }\n"); + } + } + fprintf(f, "\n"); + if (api->ret.typeName[0]) { - fprintf(f, " f->readReturn(&ret, sizeof(ret));\n"); - } else if (needFlush) { - fprintf(f, " f->readReturn(NULL, 0);\n"); + fprintf(f, " io->coreSetReturn(&ret, sizeof(ret));\n"); + } else /*if (needFlush)*/ { + fprintf(f, " io->coreSetReturn(NULL, 0);\n"); + } + + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if (vt->ptrLevel == 1) { + fprintf(f, " free((void *)cmd.%s);\n", vt->name); + } + } + for (ct2=0; ct2 < api->paramCount; ct2++) { + const VarType *vt = &api->params[ct2]; + if (vt->ptrLevel == 2) { + fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name); + fprintf(f, " free((void *)cmd.%s);\n", vt->name); + fprintf(f, " }\n"); + } } fprintf(f, "};\n\n"); @@ -608,7 +637,7 @@ int main(int argc, char **argv) { fprintf(f, " uint32_t size;\n"); fprintf(f, "} RsPlaybackRemoteHeader;\n\n"); fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n"); - fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, Fifo *, uint8_t *scratch, size_t scratchSize);\n"); + fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, ThreadIO *);\n"); fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1); fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1); diff --git a/libs/rs/tests/Android.mk b/libs/rs/tests/Android.mk new file mode 100644 index 0000000..197e862 --- /dev/null +++ b/libs/rs/tests/Android.mk @@ -0,0 +1,30 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + compute.cpp \ + ScriptC_mono.cpp + +LOCAL_SHARED_LIBRARIES := \ + libRS \ + libz \ + libcutils \ + libutils \ + libEGL \ + libGLESv1_CM \ + libGLESv2 \ + libui \ + libbcc \ + libbcinfo \ + libgui + +LOCAL_MODULE:= rstest-compute + +LOCAL_MODULE_TAGS := tests + +LOCAL_C_INCLUDES += .. \ + frameworks/base/libs/rs \ + out/target/product/stingray/obj/SHARED_LIBRARIES/libRS_intermediates + +include $(BUILD_EXECUTABLE) + diff --git a/libs/rs/tests/ScriptC_mono.cpp b/libs/rs/tests/ScriptC_mono.cpp new file mode 100644 index 0000000..7f83616 --- /dev/null +++ b/libs/rs/tests/ScriptC_mono.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008-2012 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 "ScriptC_mono.h" + +static const char mono[] = \ + "\xDE\xC0\x17\x0B\x00\x00\x00\x00\x18\x00\x00\x00\xFC\x03\x00\x00\x00\x00\x00\x00" \ + "\x10\x00\x00\x00\x42\x43\xC0\xDE\x21\x0C\x00\x00\xFC\x00\x00\x00\x01\x10\x00\x00" \ + "\x12\x00\x00\x00\x07\x81\x23\x91\x41\xC8\x04\x49\x06\x10\x32\x39\x92\x01\x84\x0C" \ + "\x25\x05\x08\x19\x1E\x04\x8B\x62\x80\x14\x45\x02\x42\x92\x0B\x42\xA4\x10\x32\x14" \ + "\x38\x08\x18\x49\x0A\x32\x44\x24\x48\x0A\x90\x21\x23\xC4\x52\x80\x0C\x19\x21\x72" \ + "\x24\x07\xC8\x48\x11\x62\xA8\xA0\xA8\x40\xC6\xF0\x01\x00\x00\x00\x49\x18\x00\x00" \ + "\x08\x00\x00\x00\x0B\x8C\x00\x04\x41\x10\x04\x09\x01\x04\x41\x10\x04\x89\xFF\xFF" \ + "\xFF\xFF\x1F\xC0\x60\x81\xF0\xFF\xFF\xFF\xFF\x03\x18\x00\x00\x00\x89\x20\x00\x00" \ + "\x13\x00\x00\x00\x32\x22\x48\x09\x20\x64\x85\x04\x93\x22\xA4\x84\x04\x93\x22\xE3" \ + "\x84\xA1\x90\x14\x12\x4C\x8A\x8C\x0B\x84\xA4\x4C\x10\x48\x23\x00\x73\x04\xC8\x30" \ + "\x02\x11\x90\x28\x03\x18\x83\xC8\x0C\xC0\x30\x02\x61\x14\xE1\x08\x42\xC3\x08\x83" \ + "\x51\x06\xA3\x14\xAD\x22\x08\x45\x6D\x20\x60\x8E\x00\x0C\x86\x11\x06\x08\x00\x00" \ + "\x13\xB0\x70\x90\x87\x76\xB0\x87\x3B\x68\x03\x77\x78\x07\x77\x28\x87\x36\x60\x87" \ + "\x74\x70\x87\x7A\xC0\x87\x36\x38\x07\x77\xA8\x87\x72\x08\x07\x71\x48\x87\x0D\xF2" \ + "\x50\x0E\x6D\x00\x0F\x7A\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06" \ + "\xE9\x10\x07\x7A\x80\x07\x7A\x80\x07\x6D\x90\x0E\x78\xA0\x07\x78\xA0\x07\x78\xD0" \ + "\x06\xE9\x10\x07\x76\xA0\x07\x71\x60\x07\x7A\x10\x07\x76\xD0\x06\xE9\x30\x07\x72" \ + "\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0\x06\xE9\x60\x07\x74\xA0\x07\x76\x40\x07" \ + "\x7A\x60\x07\x74\xD0\x06\xE6\x30\x07\x72\xA0\x07\x73\x20\x07\x7A\x30\x07\x72\xD0" \ + "\x06\xE6\x60\x07\x74\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x60\x07\x74" \ + "\xA0\x07\x76\x40\x07\x7A\x60\x07\x74\xD0\x06\xF6\x10\x07\x72\x80\x07\x7A\x60\x07" \ + "\x74\xA0\x07\x71\x20\x07\x78\xD0\x06\xE1\x00\x07\x7A\x00\x07\x7A\x60\x07\x74\xD0" \ + "\x06\xEE\x30\x07\x72\xD0\x06\xB3\x60\x07\x74\x30\x44\x29\x00\x00\x08\x00\x00\x00" \ + "\x80\x21\x4A\x02\x04\x00\x00\x00\x00\x00\x0C\x51\x18\x20\x00\x00\x00\x00\x00\x60" \ + "\x88\xE2\x00\x01\x00\x00\x00\x00\x00\x79\x18\x00\x45\x00\x00\x00\x43\x88\x27\x78" \ + "\x84\x05\x87\x3D\x94\x83\x3C\xCC\x43\x3A\xBC\x83\x3B\x2C\x08\xE2\x60\x08\xF1\x10" \ + "\x4F\xB1\x20\x52\x87\x70\xB0\x87\x70\xF8\x05\x78\x08\x87\x71\x58\x87\x70\x38\x87" \ + "\x72\xF8\x05\x77\x08\x87\x76\x28\x87\x05\x63\x30\x0E\xEF\xD0\x0E\x6E\x50\x0E\xF8" \ + "\x10\x0E\xED\x00\x0F\xEC\x50\x0E\x6E\x10\x0E\xEE\x40\x0E\xF2\xF0\x0E\xE9\x40\x0E" \ + "\x6E\x20\x0F\xF3\xE0\x06\xE8\x50\x0E\xEC\xC0\x0E\xEF\x30\x0E\xEF\xD0\x0E\xF0\x50" \ + "\x0F\xF4\x50\x0E\x43\x84\xE7\x58\x40\xC8\xC3\x3B\xBC\x03\x3D\x0C\x11\x9E\x64\x41" \ + "\x30\x07\x43\x88\x67\x79\x98\x05\xCF\x3B\xB4\x83\x3B\xA4\x03\x3C\xBC\x03\x3D\x94" \ + "\x83\x3B\xD0\x03\x18\x8C\x03\x3A\x84\x83\x3C\x0C\x21\x9E\x06\x00\x16\x44\xB3\x90" \ + "\x0E\xED\x00\x0F\xEC\x50\x0E\x60\x30\x0A\x6F\x30\x0A\x6B\xB0\x06\x60\x40\x0B\xA2" \ + "\x10\x0A\xA1\x30\xE2\x18\x03\x78\x90\x87\x70\x38\x87\x76\x08\x87\x29\x02\x30\x8C" \ + "\xB8\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE" \ + "\x41\x1E\xCA\x21\x1C\xC6\x01\x1D\x7E\xC1\x1D\xC2\xA1\x1D\xCA\x61\x4A\x60\x8C\x90" \ + "\xC6\x40\x1E\xE6\xE1\x17\xCA\x01\x1F\xE0\xE1\x1D\xE4\x81\x1E\x7E\xC1\x1C\xDE\x41" \ + "\x1E\xCA\x21\x1C\xC6\x01\x1D\xA6\x04\x08\x00\x00\x61\x20\x00\x00\x24\x00\x00\x00" \ + "\x13\x04\x41\x2C\x10\x00\x00\x00\x0C\x00\x00\x00\x04\x8B\xA0\x04\x46\x00\xE8\xCC" \ + "\x00\x90\x9A\x01\x98\x63\x70\x1A\x86\xCC\x18\x41\x6D\xFA\xB2\xEF\x8D\x11\x88\x6D" \ + "\xCC\xC6\xDF\x18\xC1\x49\x97\x72\xFA\x51\x9C\x63\x40\x0E\x63\x04\x00\x00\x00\x00" \ + "\x44\x8C\x11\x03\x42\x08\x82\x68\x90\x41\x4A\x9E\x11\x83\x42\x08\x84\x69\x99\x63" \ + "\x50\x28\x64\x90\xA1\x52\xA0\x11\x03\x42\x08\x06\x6B\x30\xA2\xB8\x06\x00\xC3\x81" \ + "\x00\x00\x00\x00\x03\x00\x00\x00\x46\x40\x54\x3F\xD2\x58\x41\x51\xFD\x0E\x35\x01" \ + "\x01\x31\x00\x00\x03\x00\x00\x00\x5B\x06\x20\x50\xB6\x0C\x47\xA0\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x79\x18\x00\x00\x0B\x00\x00\x00\x33\x08\x80\x1C\xC4\xE1\x1C\x66" \ + "\x14\x01\x3D\x88\x43\x38\x84\xC3\x8C\x42\x80\x07\x79\x78\x07\x73\x98\xB1\x0C\xE6" \ + "\x00\x0F\xE1\x30\x0E\xE3\x50\x0F\xF2\x10\x0E\xE3\x90\x0F\x00\x00\x71\x20\x00\x00" \ + "\x0E\x00\x00\x00\x06\x40\x44\x8E\x33\x59\x40\x14\x49\x6E\xF3\x00\x82\xC2\x39\x8B" \ + "\x13\xF1\x3C\xCF\x9B\x40\xF3\xCF\xF7\xE0\x4C\x5D\x75\xFF\x05\xFB\xDB\x80\xF6\xCF" \ + "\xF5\x1E\x49\x29\x20\x28\x9C\xB3\x38\x51\xEB\xF0\x3C\xCF\x77\xD5\xFD\x17\x00\x00" \ + "\x00\x00\x00\x00"; + + +ScriptC_mono::ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) : + ScriptC(rs, mono, sizeof(mono) - 1, "mono", 4, cacheDir, cacheDirLength) { + + printf("sizeof text %i", sizeof(mono)); + + + +} + +void ScriptC_mono::forEach_root(const Allocation *ain, const Allocation *aout) { + forEach(0, ain, aout, NULL, 0); +} + diff --git a/libs/rs/tests/ScriptC_mono.h b/libs/rs/tests/ScriptC_mono.h new file mode 100644 index 0000000..7e4f601 --- /dev/null +++ b/libs/rs/tests/ScriptC_mono.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2008-2012 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 "ScriptC.h" + +class ScriptC_mono : protected ScriptC { +public: + ScriptC_mono(RenderScript *rs, const char *cacheDir, size_t cacheDirLength); + + void forEach_root(const Allocation *ain, const Allocation *aout); + +}; + diff --git a/libs/rs/tests/compute.cpp b/libs/rs/tests/compute.cpp new file mode 100644 index 0000000..42eaa52 --- /dev/null +++ b/libs/rs/tests/compute.cpp @@ -0,0 +1,58 @@ + +#include "RenderScript.h" +#include "Element.h" +#include "Type.h" +#include "Allocation.h" + +#include "ScriptC_mono.h" + +int main(int argc, char** argv) +{ + + RenderScript *rs = new RenderScript(); + printf("New RS %p\n", rs); + + bool r = rs->init(16); + printf("Init returned %i\n", r); + + const Element *e = Element::RGBA_8888(rs); + printf("Element %p\n", e); + + Type::Builder tb(rs, e); + tb.setX(128); + tb.setY(128); + const Type *t = tb.create(); + printf("Type %p\n", t); + + + Allocation *a1 = Allocation::createSized(rs, e, 1000); + printf("Allocation %p\n", a1); + + Allocation *ain = Allocation::createTyped(rs, t); + Allocation *aout = Allocation::createTyped(rs, t); + printf("Allocation %p %p\n", ain, aout); + + ScriptC_mono * sc = new ScriptC_mono(rs, NULL, 0); + printf("new script\n"); + + uint32_t *buf = new uint32_t[t->getCount()]; + for (uint32_t ct=0; ct < t->getCount(); ct++) { + buf[ct] = ct | (ct << 16); + } + //ain->copy1DRangeFrom(0, 128*128, (int32_t *)buf, 128*128*4); + ain->copy1DRangeFromUnchecked(0, t->getCount(), buf, t->getCount()*4); + + + + sc->forEach_root(ain, aout); + printf("for each done\n"); + + + printf("Deleting stuff\n"); + delete sc; + delete t; + delete a1; + delete e; + delete rs; + printf("Delete OK\n"); +} diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index f8b4452..5aff7a4 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -13,41 +13,13 @@ # limitations under the License. LOCAL_PATH:= $(call my-dir) - -# libui is partially built for the host (used by build time keymap validation tool) -# These files are common to host and target builds. -commonSources:= \ - Input.cpp \ - Keyboard.cpp \ - KeyLayoutMap.cpp \ - KeyCharacterMap.cpp \ - VirtualKeyMap.cpp - -# For the host -# ===================================================== - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= $(commonSources) - -LOCAL_MODULE:= libui - -include $(BUILD_HOST_STATIC_LIBRARY) - - -# For the device -# ===================================================== - include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - $(commonSources) \ - EGLUtils.cpp \ FramebufferNativeWindow.cpp \ GraphicBuffer.cpp \ GraphicBufferAllocator.cpp \ GraphicBufferMapper.cpp \ - InputTransport.cpp \ PixelFormat.cpp \ Rect.cpp \ Region.cpp @@ -55,15 +27,11 @@ LOCAL_SRC_FILES:= \ LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils \ - libEGL \ - libpixelflinger \ - libhardware \ - libhardware_legacy \ - libskia \ - libbinder + libhardware -LOCAL_C_INCLUDES := \ - external/skia/include/core +ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),) +LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT) +endif LOCAL_MODULE:= libui diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp deleted file mode 100644 index f24a71d..0000000 --- a/libs/ui/EGLUtils.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#define LOG_TAG "EGLUtils" - -#include <cutils/log.h> -#include <utils/Errors.h> - -#include <ui/EGLUtils.h> - -#include <EGL/egl.h> - -#include <private/ui/android_natives_priv.h> - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -const char *EGLUtils::strerror(EGLint err) -{ - switch (err){ - case EGL_SUCCESS: return "EGL_SUCCESS"; - case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; - case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; - case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; - case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; - case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; - case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; - case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; - case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; - case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; - case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; - case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; - case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; - case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; - case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; - default: return "UNKNOWN"; - } -} - -status_t EGLUtils::selectConfigForPixelFormat( - EGLDisplay dpy, - EGLint const* attrs, - PixelFormat format, - EGLConfig* outConfig) -{ - EGLint numConfigs = -1, n=0; - - if (!attrs) - return BAD_VALUE; - - if (outConfig == NULL) - return BAD_VALUE; - - // Get all the "potential match" configs... - if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE) - return BAD_VALUE; - - 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; - } - } - - free(configs); - - if (i<n) { - *outConfig = config; - return NO_ERROR; - } - - return NAME_NOT_FOUND; -} - -status_t EGLUtils::selectConfigForNativeWindow( - EGLDisplay dpy, - EGLint const* attrs, - EGLNativeWindowType window, - EGLConfig* outConfig) -{ - int err; - int format; - - if (!window) - return BAD_VALUE; - - if ((err = window->query(window, NATIVE_WINDOW_FORMAT, &format)) < 0) { - return err; - } - - return selectConfigForPixelFormat(dpy, attrs, format, outConfig); -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index d1dca0c..dec99b6 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -27,25 +27,21 @@ #include <utils/threads.h> #include <utils/RefBase.h> -#include <ui/Rect.h> +#include <ui/ANativeObjectBase.h> #include <ui/FramebufferNativeWindow.h> +#include <ui/Rect.h> #include <EGL/egl.h> -#include <pixelflinger/format.h> -#include <pixelflinger/pixelflinger.h> - #include <hardware/hardware.h> #include <hardware/gralloc.h> -#include <private/ui/android_natives_priv.h> - // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- class NativeBuffer - : public EGLNativeBase< + : public ANativeObjectBase< ANativeWindowBuffer, NativeBuffer, LightRefBase<NativeBuffer> > @@ -100,6 +96,18 @@ FramebufferNativeWindow::FramebufferNativeWindow() mNumFreeBuffers = NUM_FRAME_BUFFERS; mBufferHead = mNumBuffers-1; + /* + * This does not actually change the framebuffer format. It merely + * fakes this format to surfaceflinger so that when it creates + * framebuffer surfaces it will use this format. It's really a giant + * HACK to allow interworking with buggy gralloc+GPU driver + * implementations. You should *NEVER* need to set this for shipping + * devices. + */ +#ifdef FRAMEBUFFER_FORCE_FORMAT + *((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT; +#endif + for (i = 0; i < mNumBuffers; i++) { buffers[i] = new NativeBuffer( diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index f549a37..57063e5 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -28,8 +28,6 @@ #include <ui/GraphicBufferMapper.h> #include <ui/PixelFormat.h> -#include <pixelflinger/pixelflinger.h> - namespace android { // =========================================================================== @@ -182,21 +180,6 @@ status_t GraphicBuffer::unlock() return res; } -status_t GraphicBuffer::lock(GGLSurface* sur, uint32_t usage) -{ - void* vaddr; - status_t res = GraphicBuffer::lock(usage, &vaddr); - if (res == NO_ERROR && sur) { - sur->version = sizeof(GGLSurface); - sur->width = width; - sur->height = height; - sur->stride = stride; - sur->format = format; - sur->data = static_cast<GGLubyte*>(vaddr); - } - return res; -} - size_t GraphicBuffer::getFlattenedSize() const { return (8 + (handle ? handle->numInts : 0))*sizeof(int); } diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp index ee186c8..fc1d3c2 100644 --- a/libs/ui/PixelFormat.cpp +++ b/libs/ui/PixelFormat.cpp @@ -15,13 +15,54 @@ */ #include <ui/PixelFormat.h> -#include <pixelflinger/format.h> #include <hardware/hardware.h> +// ---------------------------------------------------------------------------- namespace android { +// ---------------------------------------------------------------------------- static const int COMPONENT_YUV = 0xFF; +struct Info { + size_t size; + size_t bitsPerPixel; + struct { + uint8_t ah; + uint8_t al; + uint8_t rh; + uint8_t rl; + uint8_t gh; + uint8_t gl; + uint8_t bh; + uint8_t bl; + }; + uint8_t components; +}; + +static Info const sPixelFormatInfos[] = { + { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, + { 4, 32, {32,24, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGBA }, + { 4, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB }, + { 3, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB }, + { 2, 16, { 0, 0, 16,11, 11, 5, 5, 0 }, PixelFormatInfo::RGB }, + { 4, 32, {32,24, 24,16, 16, 8, 8, 0 }, PixelFormatInfo::RGBA }, + { 2, 16, { 1, 0, 16,11, 11, 6, 6, 1 }, PixelFormatInfo::RGBA }, + { 2, 16, { 4, 0, 16,12, 12, 8, 8, 4 }, PixelFormatInfo::RGBA }, + { 1, 8, { 8, 0, 0, 0, 0, 0, 0, 0 }, PixelFormatInfo::ALPHA}, + { 1, 8, { 0, 0, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::L }, + { 2, 16, {16, 8, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::LA }, + { 1, 8, { 0, 0, 8, 5, 5, 2, 2, 0 }, PixelFormatInfo::RGB }, +}; + +static const Info* gGetPixelFormatTable(size_t* numEntries) { + if (numEntries) { + *numEntries = sizeof(sPixelFormatInfos)/sizeof(Info); + } + return sPixelFormatInfos; +} + +// ---------------------------------------------------------------------------- + size_t PixelFormatInfo::getScanlineSize(unsigned int width) const { size_t size; @@ -77,27 +118,12 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info) } size_t numEntries; - const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format; + const Info *i = gGetPixelFormatTable(&numEntries) + format; bool valid = uint32_t(format) < numEntries; if (!valid) { return BAD_INDEX; } - #define COMPONENT(name) \ - case GGL_##name: info->components = PixelFormatInfo::name; break; - - switch (i->components) { - COMPONENT(ALPHA) - COMPONENT(RGB) - COMPONENT(RGBA) - COMPONENT(LUMINANCE) - COMPONENT(LUMINANCE_ALPHA) - default: - return BAD_INDEX; - } - - #undef COMPONENT - info->format = format; info->bytesPerPixel = i->size; info->bitsPerPixel = i->bitsPerPixel; @@ -109,9 +135,12 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info) info->l_green = i->gl; info->h_blue = i->bh; info->l_blue = i->bl; + info->components = i->components; return NO_ERROR; } +// ---------------------------------------------------------------------------- }; // namespace android +// ---------------------------------------------------------------------------- diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk index 700b604..50cad36 100644 --- a/libs/ui/tests/Android.mk +++ b/libs/ui/tests/Android.mk @@ -2,47 +2,5 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -# Build the unit tests. -test_src_files := \ - InputChannel_test.cpp \ - InputEvent_test.cpp \ - InputPublisherAndConsumer_test.cpp - -shared_libraries := \ - libcutils \ - libutils \ - libEGL \ - libbinder \ - libpixelflinger \ - libhardware \ - libhardware_legacy \ - libui \ - libstlport \ - libskia - -static_libraries := \ - libgtest \ - libgtest_main - -c_includes := \ - bionic \ - bionic/libstdc++/include \ - external/gtest/include \ - external/stlport/stlport \ - external/skia/include/core - -module_tags := eng tests - -$(foreach file,$(test_src_files), \ - $(eval include $(CLEAR_VARS)) \ - $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \ - $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \ - $(eval LOCAL_C_INCLUDES := $(c_includes)) \ - $(eval LOCAL_SRC_FILES := $(file)) \ - $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \ - $(eval LOCAL_MODULE_TAGS := $(module_tags)) \ - $(eval include $(BUILD_EXECUTABLE)) \ -) - # Build the manual test programs. include $(call all-makefiles-under, $(LOCAL_PATH)) diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk index 24cf504..a96c8e6 100644 --- a/libs/utils/Android.mk +++ b/libs/utils/Android.mk @@ -18,9 +18,6 @@ LOCAL_PATH:= $(call my-dir) # and once for the device. commonSources:= \ - Asset.cpp \ - AssetDir.cpp \ - AssetManager.cpp \ BasicHashtable.cpp \ BlobCache.cpp \ BufferedTextOutput.cpp \ @@ -29,14 +26,11 @@ commonSources:= \ FileMap.cpp \ Flattenable.cpp \ LinearTransform.cpp \ - ObbFile.cpp \ PropertyMap.cpp \ RefBase.cpp \ - ResourceTypes.cpp \ SharedBuffer.cpp \ Static.cpp \ StopWatch.cpp \ - StreamingZipInflater.cpp \ String8.cpp \ String16.cpp \ StringArray.cpp \ @@ -47,9 +41,6 @@ commonSources:= \ Tokenizer.cpp \ Unicode.cpp \ VectorImpl.cpp \ - ZipFileCRO.cpp \ - ZipFileRO.cpp \ - ZipUtils.cpp \ misc.cpp @@ -63,7 +54,6 @@ LOCAL_SRC_FILES:= $(commonSources) LOCAL_MODULE:= libutils LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS) -LOCAL_C_INCLUDES += external/zlib ifeq ($(HOST_OS),windows) ifeq ($(strip $(USE_CYGWIN),),) @@ -79,7 +69,6 @@ endif include $(BUILD_HOST_STATIC_LIBRARY) - # For the device # ===================================================== include $(CLEAR_VARS) @@ -88,8 +77,6 @@ include $(CLEAR_VARS) # we have the common sources, plus some device-specific stuff LOCAL_SRC_FILES:= \ $(commonSources) \ - BackupData.cpp \ - BackupHelpers.cpp \ Looper.cpp ifeq ($(TARGET_OS),linux) @@ -97,14 +84,11 @@ LOCAL_LDLIBS += -lrt -ldl endif LOCAL_C_INCLUDES += \ - external/zlib \ - external/icu4c/common \ bionic/libc/private LOCAL_LDLIBS += -lpthread LOCAL_SHARED_LIBRARIES := \ - libz \ liblog \ libcutils \ libdl \ @@ -113,19 +97,6 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= libutils include $(BUILD_SHARED_LIBRARY) -ifeq ($(TARGET_OS),linux) -include $(CLEAR_VARS) -LOCAL_C_INCLUDES += \ - external/zlib \ - external/icu4c/common \ - bionic/libc/private -LOCAL_LDLIBS := -lrt -ldl -lpthread -LOCAL_MODULE := libutils -LOCAL_SRC_FILES := $(commonSources) BackupData.cpp BackupHelpers.cpp -include $(BUILD_STATIC_LIBRARY) -endif - - # Include subdirectory makefiles # ============================================================ diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk index 58230f4..a6811fc 100644 --- a/libs/utils/tests/Android.mk +++ b/libs/utils/tests/Android.mk @@ -7,10 +7,8 @@ test_src_files := \ BasicHashtable_test.cpp \ BlobCache_test.cpp \ Looper_test.cpp \ - ObbFile_test.cpp \ String8_test.cpp \ Unicode_test.cpp \ - ZipFileRO_test.cpp \ shared_libraries := \ libz \ |