• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "FrameBufferAndroid.hpp"
16 #include "GrallocAndroid.hpp"
17 
18 #include <system/window.h>
19 #include <cutils/log.h>
20 
21 namespace sw
22 {
dequeueBuffer(ANativeWindow * window,ANativeWindowBuffer ** buffer)23 	inline int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer)
24 	{
25 		#if ANDROID_PLATFORM_SDK_VERSION > 16
26 			return native_window_dequeue_buffer_and_wait(window, buffer);
27 		#else
28 			return window->dequeueBuffer(window, buffer);
29 		#endif
30 	}
31 
queueBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)32 	inline int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd)
33 	{
34 		#if ANDROID_PLATFORM_SDK_VERSION > 16
35 			return window->queueBuffer(window, buffer, fenceFd);
36 		#else
37 			return window->queueBuffer(window, buffer);
38 		#endif
39 	}
40 
cancelBuffer(ANativeWindow * window,ANativeWindowBuffer * buffer,int fenceFd)41 	inline int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd)
42 	{
43 		#if ANDROID_PLATFORM_SDK_VERSION > 16
44 			return window->cancelBuffer(window, buffer, fenceFd);
45 		#else
46 			return window->cancelBuffer(window, buffer);
47 		#endif
48 	}
49 
FrameBufferAndroid(ANativeWindow * window,int width,int height)50 	FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
51 		: FrameBuffer(width, height, false, false),
52 		  nativeWindow(window), buffer(nullptr)
53 	{
54 		nativeWindow->common.incRef(&nativeWindow->common);
55 		native_window_set_usage(nativeWindow, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
56 	}
57 
~FrameBufferAndroid()58 	FrameBufferAndroid::~FrameBufferAndroid()
59 	{
60 		nativeWindow->common.decRef(&nativeWindow->common);
61 	}
62 
blit(void * source,const Rect * sourceRect,const Rect * destRect,Format sourceFormat,size_t sourceStride)63 	void FrameBufferAndroid::blit(void *source, const Rect *sourceRect, const Rect *destRect, Format sourceFormat, size_t sourceStride)
64 	{
65 		copy(source, sourceFormat, sourceStride);
66 
67 		if(buffer)
68 		{
69 			if(locked)
70 			{
71 				locked = nullptr;
72 				unlock();
73 			}
74 
75 			queueBuffer(nativeWindow, buffer, -1);
76 		}
77 	}
78 
lock()79 	void *FrameBufferAndroid::lock()
80 	{
81 		if(dequeueBuffer(nativeWindow, &buffer) != 0)
82 		{
83 			return nullptr;
84 		}
85 
86 		if(GrallocModule::getInstance()->lock(buffer->handle,
87 		                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
88 		                 0, 0, buffer->width, buffer->height, &locked) != 0)
89 		{
90 			ALOGE("%s failed to lock buffer %p", __FUNCTION__, buffer);
91 			return nullptr;
92 		}
93 
94 		if((buffer->width < width) || (buffer->height < height))
95 		{
96 			ALOGI("lock failed: buffer of %dx%d too small for window of %dx%d",
97 				  buffer->width, buffer->height, width, height);
98 			return nullptr;
99 		}
100 
101 		switch(buffer->format)
102 		{
103 		case HAL_PIXEL_FORMAT_RGB_565:   destFormat = FORMAT_R5G6B5; break;
104 		case HAL_PIXEL_FORMAT_RGBA_8888: destFormat = FORMAT_A8B8G8R8; break;
105 #if ANDROID_PLATFORM_SDK_VERSION > 16
106 		case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: destFormat = FORMAT_X8B8G8R8; break;
107 #endif
108 		case HAL_PIXEL_FORMAT_RGBX_8888: destFormat = FORMAT_X8B8G8R8; break;
109 		case HAL_PIXEL_FORMAT_BGRA_8888: destFormat = FORMAT_A8R8G8B8; break;
110 		case HAL_PIXEL_FORMAT_RGB_888:
111 			// Frame buffers are expected to have 16-bit or 32-bit colors, not 24-bit.
112 			ALOGE("Unsupported frame buffer format RGB_888"); ASSERT(false);
113 			destFormat = FORMAT_R8G8B8;   // Wrong component order.
114 			break;
115 		default:
116 			ALOGE("Unsupported frame buffer format %d", buffer->format); ASSERT(false);
117 			destFormat = FORMAT_NULL;
118 			break;
119 		}
120 
121 		stride = buffer->stride * Surface::bytes(destFormat);
122 		return locked;
123 	}
124 
unlock()125 	void FrameBufferAndroid::unlock()
126 	{
127 		if(!buffer)
128 		{
129 			ALOGE("%s: badness unlock with no active buffer", __FUNCTION__);
130 			return;
131 		}
132 
133 		locked = nullptr;
134 
135 		if(GrallocModule::getInstance()->unlock(buffer->handle) != 0)
136 		{
137 			ALOGE("%s: badness unlock failed", __FUNCTION__);
138 		}
139 	}
140 }
141 
createFrameBuffer(void * display,ANativeWindow * window,int width,int height)142 sw::FrameBuffer *createFrameBuffer(void *display, ANativeWindow* window, int width, int height)
143 {
144 	return new sw::FrameBufferAndroid(window, width, height);
145 }
146