| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //  ImagePool.cpp
 | 
					
						
							|  |  |  | //  MNN
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //  Created by MNN on 2019/02/28.
 | 
					
						
							|  |  |  | //  Copyright © 2018, Alibaba Group Holding Limited
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-27 22:16:57 +08:00
										 |  |  | #include "backend/opencl/core/ImagePool.hpp"
 | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | namespace MNN { | 
					
						
							|  |  |  | namespace OpenCL { | 
					
						
							| 
									
										
										
										
											2022-05-27 23:46:44 +08:00
										 |  |  | cl::Image* ImagePool::alloc(int w, int h, cl_channel_type type, bool separate) { | 
					
						
							|  |  |  |     if (!separate) { | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |         int minWaste  = 0; | 
					
						
							|  |  |  |         auto findIter = mFreeList.end(); | 
					
						
							|  |  |  |         for (auto iterP = mFreeList.begin(); iterP != mFreeList.end(); iterP++) { | 
					
						
							|  |  |  |             auto& iter = *iterP; | 
					
						
							| 
									
										
										
										
											2024-04-19 11:58:21 +08:00
										 |  |  |             if (iter->w >= w && iter->h >= h && iter->type == type) { | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |                 int waste = iter->w * iter->h - w * h; | 
					
						
							|  |  |  |                 if (minWaste == 0 || waste < minWaste) { | 
					
						
							|  |  |  |                     findIter = iterP; | 
					
						
							|  |  |  |                     minWaste = waste; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (findIter != mFreeList.end()) { | 
					
						
							|  |  |  |             auto image = (*findIter)->image.get(); | 
					
						
							|  |  |  |             mFreeList.erase(findIter); | 
					
						
							|  |  |  |             return image; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     std::shared_ptr<Node> node(new Node); | 
					
						
							| 
									
										
										
										
											2023-07-31 14:24:48 +08:00
										 |  |  |     cl_int ret = CL_SUCCESS; | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |     node->w = w; | 
					
						
							|  |  |  |     node->h = h; | 
					
						
							| 
									
										
										
										
											2024-04-19 11:58:21 +08:00
										 |  |  |     node->type = type; | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |     node->image.reset( | 
					
						
							| 
									
										
										
										
											2023-07-31 14:24:48 +08:00
										 |  |  |         new cl::Image2D(mContext, CL_MEM_READ_WRITE, cl::ImageFormat(CL_RGBA, type), w, h, 0, nullptr, &ret)); | 
					
						
							|  |  |  |     if (nullptr == node->image.get() || ret != CL_SUCCESS) { | 
					
						
							|  |  |  |         MNN_ERROR("Alloc Image %d x %d error, code:%d \n", w, h, ret); | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |         return nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mAllImage.insert(std::make_pair(node->image.get(), node)); | 
					
						
							|  |  |  |     return node->image.get(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ImagePool::recycle(cl::Image* image, bool release) { | 
					
						
							|  |  |  |     auto iter = mAllImage.find(image); | 
					
						
							|  |  |  |     if (iter == mAllImage.end()) { | 
					
						
							|  |  |  |         MNN_ERROR("recycle failed for not belong image\n"); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (release) { | 
					
						
							|  |  |  |         mAllImage.erase(iter); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mFreeList.push_back(iter->second); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ImagePool::clear() { | 
					
						
							|  |  |  |     mFreeList.clear(); | 
					
						
							|  |  |  |     mAllImage.clear(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-12-04 11:12:20 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | void ImagePool::releaseFreeList() { | 
					
						
							|  |  |  |     for(auto mf : mFreeList){ | 
					
						
							|  |  |  |         auto iter = mAllImage.find(mf->image.get()); | 
					
						
							|  |  |  |         if (iter != mAllImage.end()) { | 
					
						
							|  |  |  |             mAllImage.erase(iter); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mFreeList.clear(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | } // namespace OpenCL
 | 
					
						
							|  |  |  | } // namespace MNN
 |