OSDN Git Service

auto import from //depot/cupcake/@135843
[android-x86/frameworks-native.git] / libs / surfaceflinger / VRamHeap.cpp
1 /*
2  * Copyright (C) 2008 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 "SurfaceFlinger"
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <math.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/ioctl.h>
29
30 #include <cutils/log.h>
31 #include <cutils/properties.h>
32
33 #include <utils/MemoryDealer.h>
34 #include <utils/MemoryBase.h>
35 #include <utils/MemoryHeapPmem.h>
36 #include <utils/MemoryHeapBase.h>
37
38 #include "GPUHardware/GPUHardware.h"
39 #include "SurfaceFlinger.h"
40 #include "VRamHeap.h"
41
42 #if HAVE_ANDROID_OS
43 #include <linux/android_pmem.h>
44 #endif
45
46
47 namespace android {
48
49 // ---------------------------------------------------------------------------
50
51 /*
52  * Amount of memory we reserve for surface, per client in PMEM
53  * (PMEM is used for 2D acceleration)
54  * 8 MB of address space per client should be enough.
55  */
56 static const int PMEM_SIZE = int(8 * 1024 * 1024);
57
58 int SurfaceHeapManager::global_pmem_heap = 0;
59
60 // ---------------------------------------------------------------------------
61
62 SurfaceHeapManager::SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, 
63         size_t clientHeapSize)
64     : mFlinger(flinger), mClientHeapSize(clientHeapSize)
65 {
66     SurfaceHeapManager::global_pmem_heap = 1;
67 }
68
69 SurfaceHeapManager::~SurfaceHeapManager()
70 {
71 }
72
73 void SurfaceHeapManager::onFirstRef()
74 {
75     if (global_pmem_heap) {
76         const char* device = "/dev/pmem";
77         mPMemHeap = new PMemHeap(device, PMEM_SIZE);
78         if (mPMemHeap->base() == MAP_FAILED) {
79             mPMemHeap.clear();
80             global_pmem_heap = 0;
81         }
82     }
83 }
84
85 sp<MemoryDealer> SurfaceHeapManager::createHeap(
86         uint32_t flags,
87         pid_t client_pid,
88         const sp<MemoryDealer>& defaultAllocator)
89 {
90     sp<MemoryDealer> dealer; 
91
92     if (flags & ISurfaceComposer::eGPU) {
93         // don't grant GPU memory if GPU is disabled
94         char value[PROPERTY_VALUE_MAX];
95         property_get("debug.egl.hw", value, "1");
96         if (atoi(value) == 0) {
97             flags &= ~ISurfaceComposer::eGPU;
98         }
99     }
100
101     if (flags & ISurfaceComposer::eGPU) {
102         // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
103         if (!(flags & ISurfaceComposer::eSecure)) {
104             // if GPU doesn't work, we try eHardware
105             flags |= ISurfaceComposer::eHardware;
106             // asked for GPU memory, try that first
107             dealer = mFlinger->getGPU()->request(client_pid);
108         }
109     }
110
111     if (dealer == NULL) {
112         if (defaultAllocator != NULL)
113             // if a default allocator is given, use that
114             dealer = defaultAllocator;
115     }
116     
117     if (dealer == NULL) {
118         // always try h/w accelerated memory first
119         if (global_pmem_heap) {
120             const sp<PMemHeap>& heap(mPMemHeap);
121             if (dealer == NULL && heap != NULL) {
122                 dealer = new MemoryDealer( 
123                         heap->createClientHeap(),
124                         heap->getAllocator());
125             }
126         }
127     }
128
129     if (dealer == NULL) {
130         // return the ashmem allocator (software rendering)
131         dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
132     }
133     return dealer;
134 }
135
136 sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const 
137 {
138     Mutex::Autolock _l(mLock);
139     sp<SimpleBestFitAllocator> allocator;
140
141     // this is only used for debugging
142     switch (type) {
143         case NATIVE_MEMORY_TYPE_PMEM:
144             if (mPMemHeap != 0) {
145                 allocator = mPMemHeap->getAllocator();
146             }
147             break;
148     }
149     return allocator;
150 }
151
152 // ---------------------------------------------------------------------------
153
154 PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
155     : MemoryHeapBase(device, size)
156 {
157     //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
158     if (base() != MAP_FAILED) {
159         //LOGD("%s, %u bytes", device, virtualSize());
160         if (reserved == 0)
161             reserved = virtualSize();
162         mAllocator = new SimpleBestFitAllocator(reserved);
163     }
164 }
165
166 PMemHeap::~PMemHeap() {
167     //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
168 }
169
170 sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
171     sp<MemoryHeapBase> parentHeap(this);
172     return new MemoryHeapPmem(parentHeap);
173 }
174
175 // ---------------------------------------------------------------------------
176 }; // namespace android