19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Copyright 2007, The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ** limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "EGL" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ctype.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <errno.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if HAVE_ANDROID_OS 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <linux/android_pmem.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/log.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/properties.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/IMemory.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/IServiceManager.h> 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/IPCThreadState.h> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Parcel.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/EGLDisplaySurface.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/ISurfaceComposer.h> 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "hooks.h" 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "egl_impl.h" 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * we provide our own allocators for the GPU regions, these 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * allocators go through surfaceflinger 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic Mutex gRegionsLock; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic request_gpu_t gRegions; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic sp<ISurfaceComposer> gSurfaceManager; 56778fb15a010bdac0a3721193ff125fcec8e7312cMathias AgopianGL_API ISurfaceComposer* GLES_localSurfaceManager = 0; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectextern egl_connection_t gEGLImpl[2]; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst sp<ISurfaceComposer>& getSurfaceFlinger() 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(gRegionsLock); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * There is a little bit of voodoo magic here. We want to access 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * surfaceflinger for allocating GPU regions, however, when we are 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * running as part of surfaceflinger, we want to bypass the 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * service manager because surfaceflinger might not be registered yet. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SurfaceFlinger will populate "GLES_localSurfaceManager" with its 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own address, so we can just use that. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gSurfaceManager == 0) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (GLES_localSurfaceManager) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we're running in SurfaceFlinger's context 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gSurfaceManager = GLES_localSurfaceManager; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we're a remote process or not part of surfaceflinger, 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // go through the service manager 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IServiceManager> sm = defaultServiceManager(); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sm != NULL) { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> binder = sm->getService(String16("SurfaceFlinger")); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gSurfaceManager = interface_cast<ISurfaceComposer>(binder); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gSurfaceManager; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass GPURevokeRequester : public BnGPUCallback 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void gpuLost() { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger."); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST]; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic sp<GPURevokeRequester> gRevokerCallback; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectrequest_gpu_t* gpu_acquire(void* user) 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<ISurfaceComposer> server( getSurfaceFlinger() ); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(gRegionsLock); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (server == NULL) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ISurfaceComposer::gpu_info_t info; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gRevokerCallback == 0) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gRevokerCallback = new GPURevokeRequester(); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = server->requestGPU(gRevokerCallback, &info); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (err != NO_ERROR) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("requestGPU returned %d", err); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12116da7959a072da0d5fdc3a774fa01fb4d811d46fMathias Agopian if (info.regs == 0) { 12216da7959a072da0d5fdc3a774fa01fb4d811d46fMathias Agopian LOGD("requestGPU() failed"); 12316da7959a072da0d5fdc3a774fa01fb4d811d46fMathias Agopian return 0; 12416da7959a072da0d5fdc3a774fa01fb4d811d46fMathias Agopian } 12516da7959a072da0d5fdc3a774fa01fb4d811d46fMathias Agopian 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool failed = false; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project request_gpu_t* gpu = &gRegions; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(gpu, 0, sizeof(*gpu)); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info.regs != 0) { 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> heap(info.regs->getMemory()); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heap != 0) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = heap->heapID(); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->regs.fd = fd; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->regs.base = info.regs->pointer(); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->regs.size = info.regs->size(); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->regs.user = info.regs.get(); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if HAVE_ANDROID_OS 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct pmem_region region; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ioctl(fd, PMEM_GET_PHYS, ®ion) >= 0) 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->regs.phys = (void*)region.offset; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.regs->incStrong(gpu); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("GPU register handle %p is invalid!", info.regs.get()); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failed = true; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0 ; i<info.count && !failed ; i++) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory>& region(info.regions[i].region); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (region != 0) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> heap(region->getMemory()); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heap != 0) { 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int fd = heap->heapID(); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].fd = fd; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].base = region->pointer(); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].size = region->size(); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].user = region.get(); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].offset = info.regions[i].reserved; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if HAVE_ANDROID_OS 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct pmem_region reg; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ioctl(fd, PMEM_GET_PHYS, ®) >= 0) 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].phys = (void*)reg.offset; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project region->incStrong(gpu); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("GPU region handle [%d, %p] is invalid!", i, region.get()); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failed = true; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (failed) { 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // something went wrong, clean up everything! 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gpu->regs.user) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<IMemory*>(gpu->regs.user)->decStrong(gpu); 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0 ; i<info.count ; i++) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gpu->gpu[i].user) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<IMemory*>(gpu->gpu[i].user)->decStrong(gpu); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->count = info.count; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gpu; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint gpu_release(void*, request_gpu_t* gpu) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory> regs; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { // scope for lock 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(gRegionsLock); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project regs = static_cast<IMemory*>(gpu->regs.user); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->regs.user = 0; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (regs != 0) regs->decStrong(gpu); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<gpu->count ; i++) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemory> r(static_cast<IMemory*>(gpu->gpu[i].user)); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gpu->gpu[i].user = 0; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r != 0) r->decStrong(gpu); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // there is a special transaction to relinquish the GPU 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (it will happen automatically anyway if we don't do this) 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel data, reply; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // NOTE: this transaction does not require an interface token 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project regs->asBinder()->transact(1000, data, &reply); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 218