gpu.cpp revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
1/* 2 ** Copyright 2007, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17#define LOG_TAG "EGL" 18 19#include <ctype.h> 20#include <string.h> 21#include <errno.h> 22 23#include <sys/ioctl.h> 24 25#if HAVE_ANDROID_OS 26#include <linux/android_pmem.h> 27#endif 28 29#include <cutils/log.h> 30#include <cutils/properties.h> 31 32#include <utils/IMemory.h> 33#include <utils/threads.h> 34#include <utils/IServiceManager.h> 35#include <utils/IPCThreadState.h> 36#include <utils/Parcel.h> 37 38#include <ui/EGLDisplaySurface.h> 39#include <ui/ISurfaceComposer.h> 40 41#include "hooks.h" 42#include "egl_impl.h" 43 44// ---------------------------------------------------------------------------- 45namespace android { 46// ---------------------------------------------------------------------------- 47 48/* 49 * we provide our own allocators for the GPU regions, these 50 * allocators go through surfaceflinger 51 */ 52 53static Mutex gRegionsLock; 54static request_gpu_t gRegions; 55static sp<ISurfaceComposer> gSurfaceManager; 56ISurfaceComposer* GLES_localSurfaceManager = 0; 57 58extern egl_connection_t gEGLImpl[2]; 59 60const sp<ISurfaceComposer>& getSurfaceFlinger() 61{ 62 Mutex::Autolock _l(gRegionsLock); 63 64 /* 65 * There is a little bit of voodoo magic here. We want to access 66 * surfaceflinger for allocating GPU regions, however, when we are 67 * running as part of surfaceflinger, we want to bypass the 68 * service manager because surfaceflinger might not be registered yet. 69 * SurfaceFlinger will populate "GLES_localSurfaceManager" with its 70 * own address, so we can just use that. 71 */ 72 if (gSurfaceManager == 0) { 73 if (GLES_localSurfaceManager) { 74 // we're running in SurfaceFlinger's context 75 gSurfaceManager = GLES_localSurfaceManager; 76 } else { 77 // we're a remote process or not part of surfaceflinger, 78 // go through the service manager 79 sp<IServiceManager> sm = defaultServiceManager(); 80 if (sm != NULL) { 81 sp<IBinder> binder = sm->getService(String16("SurfaceFlinger")); 82 gSurfaceManager = interface_cast<ISurfaceComposer>(binder); 83 } 84 } 85 } 86 return gSurfaceManager; 87} 88 89class GPURevokeRequester : public BnGPUCallback 90{ 91public: 92 virtual void gpuLost() { 93 LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger."); 94 gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST]; 95 } 96}; 97 98static sp<GPURevokeRequester> gRevokerCallback; 99 100 101request_gpu_t* gpu_acquire(void* user) 102{ 103 sp<ISurfaceComposer> server( getSurfaceFlinger() ); 104 105 Mutex::Autolock _l(gRegionsLock); 106 if (server == NULL) { 107 return 0; 108 } 109 110 ISurfaceComposer::gpu_info_t info; 111 112 if (gRevokerCallback == 0) 113 gRevokerCallback = new GPURevokeRequester(); 114 115 status_t err = server->requestGPU(gRevokerCallback, &info); 116 if (err != NO_ERROR) { 117 LOGD("requestGPU returned %d", err); 118 return 0; 119 } 120 121 bool failed = false; 122 request_gpu_t* gpu = &gRegions; 123 memset(gpu, 0, sizeof(*gpu)); 124 125 if (info.regs != 0) { 126 sp<IMemoryHeap> heap(info.regs->getMemory()); 127 if (heap != 0) { 128 int fd = heap->heapID(); 129 gpu->regs.fd = fd; 130 gpu->regs.base = info.regs->pointer(); 131 gpu->regs.size = info.regs->size(); 132 gpu->regs.user = info.regs.get(); 133#if HAVE_ANDROID_OS 134 struct pmem_region region; 135 if (ioctl(fd, PMEM_GET_PHYS, ®ion) >= 0) 136 gpu->regs.phys = (void*)region.offset; 137#endif 138 info.regs->incStrong(gpu); 139 } else { 140 LOGE("GPU register handle %p is invalid!", info.regs.get()); 141 failed = true; 142 } 143 } 144 145 for (size_t i=0 ; i<info.count && !failed ; i++) { 146 sp<IMemory>& region(info.regions[i].region); 147 if (region != 0) { 148 sp<IMemoryHeap> heap(region->getMemory()); 149 if (heap != 0) { 150 const int fd = heap->heapID(); 151 gpu->gpu[i].fd = fd; 152 gpu->gpu[i].base = region->pointer(); 153 gpu->gpu[i].size = region->size(); 154 gpu->gpu[i].user = region.get(); 155 gpu->gpu[i].offset = info.regions[i].reserved; 156#if HAVE_ANDROID_OS 157 struct pmem_region reg; 158 if (ioctl(fd, PMEM_GET_PHYS, ®) >= 0) 159 gpu->gpu[i].phys = (void*)reg.offset; 160#endif 161 region->incStrong(gpu); 162 } else { 163 LOGE("GPU region handle [%d, %p] is invalid!", i, region.get()); 164 failed = true; 165 } 166 } 167 } 168 169 if (failed) { 170 // something went wrong, clean up everything! 171 if (gpu->regs.user) { 172 static_cast<IMemory*>(gpu->regs.user)->decStrong(gpu); 173 for (size_t i=0 ; i<info.count ; i++) { 174 if (gpu->gpu[i].user) { 175 static_cast<IMemory*>(gpu->gpu[i].user)->decStrong(gpu); 176 } 177 } 178 } 179 } 180 181 gpu->count = info.count; 182 return gpu; 183} 184 185int gpu_release(void*, request_gpu_t* gpu) 186{ 187 sp<IMemory> regs; 188 189 { // scope for lock 190 Mutex::Autolock _l(gRegionsLock); 191 regs = static_cast<IMemory*>(gpu->regs.user); 192 gpu->regs.user = 0; 193 if (regs != 0) regs->decStrong(gpu); 194 195 for (int i=0 ; i<gpu->count ; i++) { 196 sp<IMemory> r(static_cast<IMemory*>(gpu->gpu[i].user)); 197 gpu->gpu[i].user = 0; 198 if (r != 0) r->decStrong(gpu); 199 } 200 } 201 202 // there is a special transaction to relinquish the GPU 203 // (it will happen automatically anyway if we don't do this) 204 Parcel data, reply; 205 // NOTE: this transaction does not require an interface token 206 regs->asBinder()->transact(1000, data, &reply); 207 return 1; 208} 209 210// ---------------------------------------------------------------------------- 211}; // namespace android 212// ---------------------------------------------------------------------------- 213