|  | /* | 
|  | * Copyright (C) 2018 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 "Context.h" | 
|  | #include "Device.h" | 
|  |  | 
|  | #include <android-base/logging.h> | 
|  | #include <android/dlext.h> | 
|  | #include <dlfcn.h> | 
|  |  | 
|  | namespace android { | 
|  | namespace hardware { | 
|  | namespace renderscript { | 
|  | namespace V1_0 { | 
|  | namespace implementation { | 
|  |  | 
|  |  | 
|  | static dispatchTable loadHAL(); | 
|  | dispatchTable Device::mDispatchHal = loadHAL(); | 
|  |  | 
|  | Device::Device() { | 
|  | } | 
|  |  | 
|  | dispatchTable& Device::getHal() { | 
|  | return mDispatchHal; | 
|  | } | 
|  |  | 
|  |  | 
|  | // Methods from ::android::hardware::renderscript::V1_0::IDevice follow. | 
|  |  | 
|  | Return<sp<IContext>> Device::contextCreate(uint32_t sdkVersion, ContextType ct, int32_t flags) { | 
|  | return new Context(sdkVersion, ct, flags); | 
|  | } | 
|  |  | 
|  |  | 
|  | // Methods from ::android::hidl::base::V1_0::IBase follow. | 
|  |  | 
|  | IDevice* HIDL_FETCH_IDevice(const char* /* name */) { | 
|  | return new Device(); | 
|  | } | 
|  |  | 
|  | // Helper function | 
|  | dispatchTable loadHAL() { | 
|  |  | 
|  | static_assert(sizeof(void*) <= sizeof(uint64_t), "RenderScript HIDL Error: sizeof(void*) > sizeof(uint64_t)"); | 
|  | static_assert(sizeof(size_t) <= sizeof(uint64_t), "RenderScript HIDL Error: sizeof(size_t) > sizeof(uint64_t)"); | 
|  |  | 
|  | const char* filename = "libRS_internal.so"; | 
|  | // Try to load libRS_internal.so from the "rs" namespace directly. | 
|  | typedef struct android_namespace_t* (*GetExportedNamespaceFnPtr)(const char*); | 
|  | GetExportedNamespaceFnPtr getExportedNamespace = reinterpret_cast<GetExportedNamespaceFnPtr>( | 
|  | dlsym(RTLD_DEFAULT, "android_get_exported_namespace")); | 
|  | void* handle = nullptr; | 
|  | if (getExportedNamespace != nullptr) { | 
|  | android_namespace_t* rsNamespace = getExportedNamespace("rs"); | 
|  | if (rsNamespace != nullptr) { | 
|  | const android_dlextinfo dlextinfo = { | 
|  | .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = rsNamespace, | 
|  | }; | 
|  | handle = android_dlopen_ext(filename, RTLD_LAZY | RTLD_LOCAL, &dlextinfo); | 
|  | if (handle == nullptr) { | 
|  | LOG(WARNING) << "android_dlopen_ext(" << filename << ") failed: " << dlerror(); | 
|  | } | 
|  | } | 
|  | } | 
|  | if (handle == nullptr) { | 
|  | // if there is no "rs" namespace (in case when this HAL impl is loaded | 
|  | // into a vendor process), then use the plain dlopen. | 
|  | handle = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); | 
|  | if (handle == nullptr) { | 
|  | LOG(FATAL) << "dlopen(" << filename << ") failed: " << dlerror(); | 
|  | } | 
|  | } | 
|  |  | 
|  | dispatchTable dispatchHal = { | 
|  | .SetNativeLibDir = (SetNativeLibDirFnPtr) nullptr, | 
|  |  | 
|  | .Allocation1DData = (Allocation1DDataFnPtr)dlsym(handle, "rsAllocation1DData"), | 
|  | .Allocation1DElementData = (Allocation1DElementDataFnPtr) nullptr, | 
|  | .Allocation1DRead = (Allocation1DReadFnPtr)dlsym(handle, "rsAllocation1DRead"), | 
|  | .Allocation2DData = (Allocation2DDataFnPtr)dlsym(handle, "rsAllocation2DData"), | 
|  | .Allocation2DRead = (Allocation2DReadFnPtr)dlsym(handle, "rsAllocation2DRead"), | 
|  | .Allocation3DData = (Allocation3DDataFnPtr)dlsym(handle, "rsAllocation3DData"), | 
|  | .Allocation3DRead = (Allocation3DReadFnPtr)dlsym(handle, "rsAllocation3DRead"), | 
|  | .AllocationAdapterCreate = | 
|  | (AllocationAdapterCreateFnPtr)dlsym(handle, "rsAllocationAdapterCreate"), | 
|  | .AllocationAdapterOffset = | 
|  | (AllocationAdapterOffsetFnPtr)dlsym(handle, "rsAllocationAdapterOffset"), | 
|  | .AllocationCopy2DRange = | 
|  | (AllocationCopy2DRangeFnPtr)dlsym(handle, "rsAllocationCopy2DRange"), | 
|  | .AllocationCopy3DRange = | 
|  | (AllocationCopy3DRangeFnPtr)dlsym(handle, "rsAllocationCopy3DRange"), | 
|  | .AllocationCopyToBitmap = | 
|  | (AllocationCopyToBitmapFnPtr)dlsym(handle, "rsAllocationCopyToBitmap"), | 
|  | .AllocationCreateFromBitmap = | 
|  | (AllocationCreateFromBitmapFnPtr)dlsym(handle, "rsAllocationCreateFromBitmap"), | 
|  | .AllocationCreateStrided = | 
|  | (AllocationCreateStridedFnPtr)dlsym(handle, "rsAllocationCreateStrided"), | 
|  | .AllocationCreateTyped = | 
|  | (AllocationCreateTypedFnPtr)dlsym(handle, "rsAllocationCreateTyped"), | 
|  | .AllocationCubeCreateFromBitmap = (AllocationCubeCreateFromBitmapFnPtr)dlsym( | 
|  | handle, "rsAllocationCubeCreateFromBitmap"), | 
|  | .AllocationElementData = | 
|  | (AllocationElementDataFnPtr)dlsym(handle, "rsAllocationElementData"), | 
|  | .AllocationElementRead = | 
|  | (AllocationElementReadFnPtr)dlsym(handle, "rsAllocationElementRead"), | 
|  | .AllocationGenerateMipmaps = | 
|  | (AllocationGenerateMipmapsFnPtr)dlsym(handle, "rsAllocationGenerateMipmaps"), | 
|  | .AllocationGetPointer = | 
|  | (AllocationGetPointerFnPtr)dlsym(handle, "rsAllocationGetPointer"), | 
|  | .AllocationGetSurface = | 
|  | (AllocationGetSurfaceFnPtr)dlsym(handle, "rsAllocationGetSurface"), | 
|  | .AllocationGetType = (AllocationGetTypeFnPtr)dlsym(handle, "rsaAllocationGetType"), | 
|  | .AllocationIoReceive = (AllocationIoReceiveFnPtr)dlsym(handle, "rsAllocationIoReceive"), | 
|  | .AllocationIoSend = (AllocationIoSendFnPtr)dlsym(handle, "rsAllocationIoSend"), | 
|  | .AllocationRead = (AllocationReadFnPtr)dlsym(handle, "rsAllocationRead"), | 
|  | .AllocationResize1D = (AllocationResize1DFnPtr)dlsym(handle, "rsAllocationResize1D"), | 
|  | .AllocationSetSurface = | 
|  | (AllocationSetSurfaceFnPtr)dlsym(handle, "rsAllocationSetSurface"), | 
|  | .AllocationSyncAll = (AllocationSyncAllFnPtr)dlsym(handle, "rsAllocationSyncAll"), | 
|  | .AllocationSetupBufferQueue = | 
|  | (AllocationSetupBufferQueueFnPtr)dlsym(handle, "rsAllocationSetupBufferQueue"), | 
|  | .AllocationShareBufferQueue = | 
|  | (AllocationShareBufferQueueFnPtr)dlsym(handle, "rsAllocationShareBufferQueue"), | 
|  | .AssignName = (AssignNameFnPtr)dlsym(handle, "rsAssignName"), | 
|  | .ClosureCreate = (ClosureCreateFnPtr)dlsym(handle, "rsClosureCreate"), | 
|  | .ClosureSetArg = (ClosureSetArgFnPtr)dlsym(handle, "rsClosureSetArg"), | 
|  | .ClosureSetGlobal = (ClosureSetGlobalFnPtr)dlsym(handle, "rsClosureSetGlobal"), | 
|  | .ContextCreateVendor = (ContextCreateVendorFnPtr)dlsym(handle, "rsContextCreateVendor"), | 
|  | .ContextDeinitToClient = | 
|  | (ContextDeinitToClientFnPtr)dlsym(handle, "rsContextDeinitToClient"), | 
|  | .ContextDestroy = (ContextDestroyFnPtr)dlsym(handle, "rsContextDestroy"), | 
|  | .ContextDump = (ContextDumpFnPtr)dlsym(handle, "rsContextDump"), | 
|  | .ContextFinish = (ContextFinishFnPtr)dlsym(handle, "rsContextFinish"), | 
|  | .ContextGetMessage = (ContextGetMessageFnPtr)dlsym(handle, "rsContextGetMessage"), | 
|  | .ContextInitToClient = (ContextInitToClientFnPtr)dlsym(handle, "rsContextInitToClient"), | 
|  | .ContextPeekMessage = (ContextPeekMessageFnPtr)dlsym(handle, "rsContextPeekMessage"), | 
|  | .ContextSendMessage = (ContextSendMessageFnPtr)dlsym(handle, "rsContextSendMessage"), | 
|  | .ContextSetPriority = (ContextSetPriorityFnPtr)dlsym(handle, "rsContextSetPriority"), | 
|  | .ContextSetCacheDir = (ContextSetCacheDirFnPtr)dlsym(handle, "rsContextSetCacheDir"), | 
|  | .DeviceCreate = (DeviceCreateFnPtr) nullptr, | 
|  | .DeviceDestroy = (DeviceDestroyFnPtr) nullptr, | 
|  | .DeviceSetConfig = (DeviceSetConfigFnPtr) nullptr, | 
|  | .ElementCreate2 = (ElementCreate2FnPtr)dlsym(handle, "rsElementCreate2"), | 
|  | .ElementCreate = (ElementCreateFnPtr)dlsym(handle, "rsElementCreate"), | 
|  | .ElementGetNativeData = | 
|  | (ElementGetNativeDataFnPtr)dlsym(handle, "rsaElementGetNativeData"), | 
|  | .ElementGetSubElements = | 
|  | (ElementGetSubElementsFnPtr)dlsym(handle, "rsaElementGetSubElements"), | 
|  | .GetName = (GetNameFnPtr)dlsym(handle, "rsaGetName"), | 
|  | .InvokeClosureCreate = (InvokeClosureCreateFnPtr)dlsym(handle, "rsInvokeClosureCreate"), | 
|  | .ObjDestroy = (ObjDestroyFnPtr)dlsym(handle, "rsObjDestroy"), | 
|  | .SamplerCreate = (SamplerCreateFnPtr)dlsym(handle, "rsSamplerCreate"), | 
|  | .ScriptBindAllocation = | 
|  | (ScriptBindAllocationFnPtr)dlsym(handle, "rsScriptBindAllocation"), | 
|  | .ScriptCCreate = (ScriptCCreateFnPtr)dlsym(handle, "rsScriptCCreate"), | 
|  | .ScriptFieldIDCreate = (ScriptFieldIDCreateFnPtr)dlsym(handle, "rsScriptFieldIDCreate"), | 
|  | .ScriptForEach = (ScriptForEachFnPtr) nullptr, | 
|  | .ScriptForEachMulti = (ScriptForEachMultiFnPtr)dlsym(handle, "rsScriptForEachMulti"), | 
|  | .ScriptGetVarV = (ScriptGetVarVFnPtr)dlsym(handle, "rsScriptGetVarV"), | 
|  | .ScriptGroup2Create = (ScriptGroup2CreateFnPtr)dlsym(handle, "rsScriptGroup2Create"), | 
|  | .ScriptGroupCreate = (ScriptGroupCreateFnPtr)dlsym(handle, "rsScriptGroupCreate"), | 
|  | .ScriptGroupExecute = (ScriptGroupExecuteFnPtr)dlsym(handle, "rsScriptGroupExecute"), | 
|  | .ScriptGroupSetInput = (ScriptGroupSetInputFnPtr)dlsym(handle, "rsScriptGroupSetInput"), | 
|  | .ScriptGroupSetOutput = | 
|  | (ScriptGroupSetOutputFnPtr)dlsym(handle, "rsScriptGroupSetOutput"), | 
|  | .ScriptIntrinsicCreate = | 
|  | (ScriptIntrinsicCreateFnPtr)dlsym(handle, "rsScriptIntrinsicCreate"), | 
|  | .ScriptInvoke = (ScriptInvokeFnPtr)dlsym(handle, "rsScriptInvoke"), | 
|  | .ScriptInvokeIDCreate = | 
|  | (ScriptInvokeIDCreateFnPtr)dlsym(handle, "rsScriptInvokeIDCreate"), | 
|  | .ScriptInvokeV = (ScriptInvokeVFnPtr)dlsym(handle, "rsScriptInvokeV"), | 
|  | .ScriptKernelIDCreate = | 
|  | (ScriptKernelIDCreateFnPtr)dlsym(handle, "rsScriptKernelIDCreate"), | 
|  | .ScriptReduce = (ScriptReduceFnPtr)dlsym(handle, "rsScriptReduce"), | 
|  | .ScriptSetTimeZone = (ScriptSetTimeZoneFnPtr)dlsym(handle, "rsScriptSetTimeZone"), | 
|  | .ScriptSetVarD = (ScriptSetVarDFnPtr)dlsym(handle, "rsScriptSetVarD"), | 
|  | .ScriptSetVarF = (ScriptSetVarFFnPtr)dlsym(handle, "rsScriptSetVarF"), | 
|  | .ScriptSetVarI = (ScriptSetVarIFnPtr)dlsym(handle, "rsScriptSetVarI"), | 
|  | .ScriptSetVarJ = (ScriptSetVarJFnPtr)dlsym(handle, "rsScriptSetVarJ"), | 
|  | .ScriptSetVarObj = (ScriptSetVarObjFnPtr)dlsym(handle, "rsScriptSetVarObj"), | 
|  | .ScriptSetVarVE = (ScriptSetVarVEFnPtr)dlsym(handle, "rsScriptSetVarVE"), | 
|  | .ScriptSetVarV = (ScriptSetVarVFnPtr)dlsym(handle, "rsScriptSetVarV"), | 
|  | .TypeCreate = (TypeCreateFnPtr)dlsym(handle, "rsTypeCreate"), | 
|  | .TypeGetNativeData = (TypeGetNativeDataFnPtr)dlsym(handle, "rsaTypeGetNativeData"), | 
|  | }; | 
|  |  | 
|  | return dispatchHal; | 
|  | } | 
|  |  | 
|  | }  // namespace implementation | 
|  | }  // namespace V1_0 | 
|  | }  // namespace renderscript | 
|  | }  // namespace hardware | 
|  | }  // namespace android |