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, &region) >= 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, &reg) >= 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