blob: 345a0b6024e093c79a1d28bf3c3caf0cfa9d0f5d [file] [log] [blame]
Nicolas Capens80d6f172016-05-13 19:30:12 -04001// 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
Greg Hartman8b5b5122015-03-20 13:05:34 -070015#include "FrameBufferAndroid.hpp"
Nicolas Capens708c24b2017-10-26 13:07:10 -040016
Stephen Whitee6ab01f2019-04-04 14:31:25 -040017#ifndef ANDROID_NDK_BUILD
Nicolas Capens708c24b2017-10-26 13:07:10 -040018#include "Common/GrallocAndroid.hpp"
Nicolas Capens9cb01cf2017-08-04 09:36:32 -040019#include <system/window.h>
Stephen Whitee6ab01f2019-04-04 14:31:25 -040020#else
21#include <android/native_window.h>
22#endif
Greg Hartman8b5b5122015-03-20 13:05:34 -070023
24namespace sw
25{
Stephen Whitee6ab01f2019-04-04 14:31:25 -040026#if !defined(ANDROID_NDK_BUILD)
Greg Hartman3b876b92015-12-01 20:07:21 -080027 inline int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer)
28 {
29 #if ANDROID_PLATFORM_SDK_VERSION > 16
30 return native_window_dequeue_buffer_and_wait(window, buffer);
31 #else
32 return window->dequeueBuffer(window, buffer);
33 #endif
34 }
35
36 inline int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd)
37 {
38 #if ANDROID_PLATFORM_SDK_VERSION > 16
39 return window->queueBuffer(window, buffer, fenceFd);
40 #else
41 return window->queueBuffer(window, buffer);
42 #endif
43 }
44
45 inline int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd)
46 {
47 #if ANDROID_PLATFORM_SDK_VERSION > 16
48 return window->cancelBuffer(window, buffer, fenceFd);
49 #else
50 return window->cancelBuffer(window, buffer);
51 #endif
52 }
Stephen Whitee6ab01f2019-04-04 14:31:25 -040053#endif // !defined(ANDROID_NDK_BUILD)
Greg Hartman3b876b92015-12-01 20:07:21 -080054
Nicolas Capens0bac2852016-05-07 06:09:58 -040055 FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
56 : FrameBuffer(width, height, false, false),
Jason Macnak1de497c2020-04-08 11:31:50 -070057 nativeWindow(window), buffer(nullptr)
Nicolas Capens0bac2852016-05-07 06:09:58 -040058 {
Stephen Whitee6ab01f2019-04-04 14:31:25 -040059#ifndef ANDROID_NDK_BUILD
Nicolas Capens0bac2852016-05-07 06:09:58 -040060 nativeWindow->common.incRef(&nativeWindow->common);
61 native_window_set_usage(nativeWindow, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
Stephen Whitee6ab01f2019-04-04 14:31:25 -040062#endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040063 }
Greg Hartman8b5b5122015-03-20 13:05:34 -070064
Nicolas Capens0bac2852016-05-07 06:09:58 -040065 FrameBufferAndroid::~FrameBufferAndroid()
66 {
Stephen Whitee6ab01f2019-04-04 14:31:25 -040067#ifndef ANDROID_NDK_BUILD
Nicolas Capens0bac2852016-05-07 06:09:58 -040068 nativeWindow->common.decRef(&nativeWindow->common);
Stephen Whitee6ab01f2019-04-04 14:31:25 -040069#endif
Nicolas Capens0bac2852016-05-07 06:09:58 -040070 }
71
Nicolas Capens241f7892015-12-30 23:40:45 -050072 void FrameBufferAndroid::blit(sw::Surface *source, const Rect *sourceRect, const Rect *destRect)
Nicolas Capens0bac2852016-05-07 06:09:58 -040073 {
Nicolas Capens241f7892015-12-30 23:40:45 -050074 copy(source);
Nicolas Capens0bac2852016-05-07 06:09:58 -040075
76 if(buffer)
Greg Hartman4d614fd2015-04-29 21:37:52 -070077 {
Nicolas Capense5a96372017-08-11 15:14:25 -040078 if(framebuffer)
Greg Hartman5f3d23c2015-05-12 20:57:51 -070079 {
Nicolas Capense5a96372017-08-11 15:14:25 -040080 framebuffer = nullptr;
Greg Hartman5f3d23c2015-05-12 20:57:51 -070081 unlock();
82 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040083
Stephen Whitee6ab01f2019-04-04 14:31:25 -040084#ifndef ANDROID_NDK_BUILD
Nicolas Capensd7f3cc82017-02-16 20:32:45 -050085 queueBuffer(nativeWindow, buffer, -1);
Stephen Whitee6ab01f2019-04-04 14:31:25 -040086#endif
Greg Hartman4d614fd2015-04-29 21:37:52 -070087 }
Nicolas Capens0bac2852016-05-07 06:09:58 -040088 }
Greg Hartman8b5b5122015-03-20 13:05:34 -070089
Nicolas Capens0bac2852016-05-07 06:09:58 -040090 void *FrameBufferAndroid::lock()
91 {
Stephen Whitee6ab01f2019-04-04 14:31:25 -040092
93#if defined(ANDROID_NDK_BUILD)
94 ANativeWindow_Buffer surfaceBuffer;
95 if (ANativeWindow_lock(nativeWindow, &surfaceBuffer, nullptr) != 0) {
96 TRACE("%s failed to lock buffer %p", __FUNCTION__, buffer);
97 return nullptr;
98 }
99 framebuffer = surfaceBuffer.bits;
100
101 if((surfaceBuffer.width < width) || (surfaceBuffer.height < height))
102 {
103 TRACE("lock failed: buffer of %dx%d too small for window of %dx%d",
Jason Macnak1de497c2020-04-08 11:31:50 -0700104 surfaceBuffer.width, surfaceBuffer.height, width, height);
Stephen Whitee6ab01f2019-04-04 14:31:25 -0400105 return nullptr;
106 }
107
108 switch(surfaceBuffer.format)
109 {
110 case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: format = FORMAT_A8B8G8R8; break;
111 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: format = FORMAT_X8B8G8R8; break;
112 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
113 // Frame buffers are expected to have 16-bit or 32-bit colors, not 24-bit.
114 TRACE("Unsupported frame buffer format R8G8B8"); ASSERT(false);
115 format = FORMAT_R8G8B8; // Wrong component order.
116 break;
117 case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: format = FORMAT_R5G6B5; break;
118 default:
119 TRACE("Unsupported frame buffer format %d", surfaceBuffer.format); ASSERT(false);
120 format = FORMAT_NULL;
121 break;
122 }
123 stride = surfaceBuffer.stride * Surface::bytes(format);
124#else // !defined(ANDROID_NDK_BUILD)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400125 if(dequeueBuffer(nativeWindow, &buffer) != 0)
126 {
127 return nullptr;
128 }
Jason Macnak1de497c2020-04-08 11:31:50 -0700129 if(GrallocModule::getInstance()->import(buffer->handle, &bufferImportedHandle) != 0) {
130 TRACE("%s failed to import buffer %p", __FUNCTION__, buffer);
131 return nullptr;
132 }
133
134 if(GrallocModule::getInstance()->lock(bufferImportedHandle,
135 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
136 0, 0, buffer->width, buffer->height, &framebuffer) != 0)
Nicolas Capens0bac2852016-05-07 06:09:58 -0400137 {
Alistair Strachanc28d28a2018-03-24 12:24:00 -0700138 TRACE("%s failed to lock buffer %p", __FUNCTION__, buffer);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400139 return nullptr;
140 }
Greg Hartman8b5b5122015-03-20 13:05:34 -0700141
Nicolas Capens0bac2852016-05-07 06:09:58 -0400142 if((buffer->width < width) || (buffer->height < height))
Greg Hartman4d614fd2015-04-29 21:37:52 -0700143 {
Alistair Strachanc28d28a2018-03-24 12:24:00 -0700144 TRACE("lock failed: buffer of %dx%d too small for window of %dx%d",
Jason Macnak1de497c2020-04-08 11:31:50 -0700145 buffer->width, buffer->height, width, height);
Nicolas Capens0bac2852016-05-07 06:09:58 -0400146 return nullptr;
Greg Hartman4d614fd2015-04-29 21:37:52 -0700147 }
148
Nicolas Capens4e0d6f62015-03-27 21:47:49 -0400149 switch(buffer->format)
150 {
Nicolas Capense5a96372017-08-11 15:14:25 -0400151 case HAL_PIXEL_FORMAT_RGB_565: format = FORMAT_R5G6B5; break;
152 case HAL_PIXEL_FORMAT_RGBA_8888: format = FORMAT_A8B8G8R8; break;
Greg Hartmanefe1ce92017-01-27 09:22:31 -0800153#if ANDROID_PLATFORM_SDK_VERSION > 16
Nicolas Capense5a96372017-08-11 15:14:25 -0400154 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: format = FORMAT_X8B8G8R8; break;
Greg Hartmanefe1ce92017-01-27 09:22:31 -0800155#endif
Nicolas Capense5a96372017-08-11 15:14:25 -0400156 case HAL_PIXEL_FORMAT_RGBX_8888: format = FORMAT_X8B8G8R8; break;
157 case HAL_PIXEL_FORMAT_BGRA_8888: format = FORMAT_A8R8G8B8; break;
Nicolas Capensa5aed5e2017-08-04 17:19:08 -0400158 case HAL_PIXEL_FORMAT_RGB_888:
159 // Frame buffers are expected to have 16-bit or 32-bit colors, not 24-bit.
Alistair Strachanc28d28a2018-03-24 12:24:00 -0700160 TRACE("Unsupported frame buffer format RGB_888"); ASSERT(false);
Nicolas Capense5a96372017-08-11 15:14:25 -0400161 format = FORMAT_R8G8B8; // Wrong component order.
Nicolas Capensa5aed5e2017-08-04 17:19:08 -0400162 break;
163 default:
Alistair Strachanc28d28a2018-03-24 12:24:00 -0700164 TRACE("Unsupported frame buffer format %d", buffer->format); ASSERT(false);
Nicolas Capense5a96372017-08-11 15:14:25 -0400165 format = FORMAT_NULL;
Nicolas Capensa5aed5e2017-08-04 17:19:08 -0400166 break;
Nicolas Capens4e0d6f62015-03-27 21:47:49 -0400167 }
Nicolas Capense5a96372017-08-11 15:14:25 -0400168 stride = buffer->stride * Surface::bytes(format);
Stephen Whitee6ab01f2019-04-04 14:31:25 -0400169#endif // !defined(ANDROID_NDK_BUILD)
170
Nicolas Capense5a96372017-08-11 15:14:25 -0400171 return framebuffer;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400172 }
Greg Hartman8b5b5122015-03-20 13:05:34 -0700173
Nicolas Capens0bac2852016-05-07 06:09:58 -0400174 void FrameBufferAndroid::unlock()
175 {
176 if(!buffer)
Greg Hartmana3aca1f2015-05-05 18:20:05 -0700177 {
Alistair Strachanc28d28a2018-03-24 12:24:00 -0700178 TRACE("%s: badness unlock with no active buffer", __FUNCTION__);
Greg Hartmana3aca1f2015-05-05 18:20:05 -0700179 return;
180 }
Nicolas Capens0bac2852016-05-07 06:09:58 -0400181
Nicolas Capense5a96372017-08-11 15:14:25 -0400182 framebuffer = nullptr;
Nicolas Capens0bac2852016-05-07 06:09:58 -0400183
Stephen Whitee6ab01f2019-04-04 14:31:25 -0400184#ifdef ANDROID_NDK_BUILD
185 ANativeWindow_unlockAndPost(nativeWindow);
186#else
Jason Macnak1de497c2020-04-08 11:31:50 -0700187 if(GrallocModule::getInstance()->unlock(bufferImportedHandle) != 0)
Greg Hartmana3aca1f2015-05-05 18:20:05 -0700188 {
Alistair Strachanc28d28a2018-03-24 12:24:00 -0700189 TRACE("%s: badness unlock failed", __FUNCTION__);
Greg Hartmana3aca1f2015-05-05 18:20:05 -0700190 }
Jason Macnak1de497c2020-04-08 11:31:50 -0700191 if(GrallocModule::getInstance()->release(bufferImportedHandle) != 0) {
192 TRACE("%s: badness release failed", __FUNCTION__);
193 }
Stephen Whitee6ab01f2019-04-04 14:31:25 -0400194#endif
Nicolas Capens0bac2852016-05-07 06:09:58 -0400195 }
Greg Hartman8b5b5122015-03-20 13:05:34 -0700196}
197
Nicolas Capensa2308052015-04-15 16:50:21 -0400198sw::FrameBuffer *createFrameBuffer(void *display, ANativeWindow* window, int width, int height)
Greg Hartman8b5b5122015-03-20 13:05:34 -0700199{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400200 return new sw::FrameBufferAndroid(window, width, height);
Greg Hartman8b5b5122015-03-20 13:05:34 -0700201}