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 21namespace sw 22{ 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 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 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 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 58 FrameBufferAndroid::~FrameBufferAndroid() 59 { 60 nativeWindow->common.decRef(&nativeWindow->common); 61 } 62 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 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 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 142sw::FrameBuffer *createFrameBuffer(void *display, ANativeWindow* window, int width, int height) 143{ 144 return new sw::FrameBufferAndroid(window, width, height); 145} 146