SoftwareRenderer.cpp revision 760f92f8b6da9c9cf128cb18fe3c09402fdde6cd
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SoftwareRenderer" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2089e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "../include/SoftwareRenderer.h" 2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber 229dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber#include <cutils/properties.h> // for property_get 23f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h> 24475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu#include <media/stagefright/foundation/AMessage.h> 259eeafeb52fecf90882e9b44eeefcb7c3e16aa915Mathias Agopian#include <system/window.h> 265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h> 278ba01021b573889802e67e029225a96f0dfa471aAndy McFadden#include <gui/IGraphicBufferProducer.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 319dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huberstatic bool runningInEmulator() { 329dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber char prop[PROPERTY_VALUE_MAX]; 339dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber return (property_get("ro.kernel.qemu", prop, NULL) > 0); 349dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber} 359dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber 36475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wustatic int ALIGN(int x, int y) { 37475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu // y must be a power of 2. 38475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu return (x + y - 1) & ~(y - 1); 39475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu} 40475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 41475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::SoftwareRenderer(const sp<ANativeWindow> &nativeWindow) 42475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu : mColorFormat(OMX_COLOR_FormatUnused), 43475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mConverter(NULL), 445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mYUVMode(None), 45475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mNativeWindow(nativeWindow), 46475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mWidth(0), 47475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mHeight(0), 48475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropLeft(0), 49475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropTop(0), 50475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropRight(0), 51475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropBottom(0), 52475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropWidth(0), 53475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropHeight(0) { 54475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu} 55475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 56475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::~SoftwareRenderer() { 57475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu delete mConverter; 58475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mConverter = NULL; 59475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu} 60475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 61475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wuvoid SoftwareRenderer::resetFormatIfChanged(const sp<AMessage> &format) { 62475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu CHECK(format != NULL); 63475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 64475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t colorFormatNew; 65475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu CHECK(format->findInt32("color-format", &colorFormatNew)); 66475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 67475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t widthNew, heightNew; 68a694dd0ce2caaf921f7bc894df87a5d52594b4ebRonghua Wu CHECK(format->findInt32("stride", &widthNew)); 69a694dd0ce2caaf921f7bc894df87a5d52594b4ebRonghua Wu CHECK(format->findInt32("slice-height", &heightNew)); 70475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 71475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew; 72475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (!format->findRect( 73475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu "crop", &cropLeftNew, &cropTopNew, &cropRightNew, &cropBottomNew)) { 74475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu cropLeftNew = cropTopNew = 0; 75475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu cropRightNew = widthNew - 1; 76475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu cropBottomNew = heightNew - 1; 77f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber } 78f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 79475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (static_cast<int32_t>(mColorFormat) == colorFormatNew && 80475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mWidth == widthNew && 81475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mHeight == heightNew && 82475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropLeft == cropLeftNew && 83475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropTop == cropTopNew && 84475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropRight == cropRightNew && 85475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropBottom == cropBottomNew) { 86475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu // Nothing changed, no need to reset renderer. 87475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu return; 88475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 89475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 90475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mColorFormat = static_cast<OMX_COLOR_FORMATTYPE>(colorFormatNew); 91475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mWidth = widthNew; 92475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mHeight = heightNew; 93475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropLeft = cropLeftNew; 94475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropTop = cropTopNew; 95475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropRight = cropRightNew; 96475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mCropBottom = cropBottomNew; 97475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber mCropWidth = mCropRight - mCropLeft + 1; 993571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber mCropHeight = mCropBottom - mCropTop + 1; 1003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 101448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith // by default convert everything to RGB565 102448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith int halFormat = HAL_PIXEL_FORMAT_RGB_565; 103448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith size_t bufWidth = mCropWidth; 104448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith size_t bufHeight = mCropHeight; 105448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith 106448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith // hardware has YUV12 and RGBA8888 support, so convert known formats 107448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith if (!runningInEmulator()) { 108448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith switch (mColorFormat) { 109448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith case OMX_COLOR_FormatYUV420Planar: 1103f9b0cc8c71ce6064bf2ed5c3ab5b48e74937385Lajos Molnar case OMX_COLOR_FormatYUV420SemiPlanar: 111448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: 112448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith { 1139dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber halFormat = HAL_PIXEL_FORMAT_YV12; 1149dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber bufWidth = (mCropWidth + 1) & ~1; 1159dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber bufHeight = (mCropHeight + 1) & ~1; 1169dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber break; 1179dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber } 118448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith case OMX_COLOR_Format24bitRGB888: 119448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith { 120448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith halFormat = HAL_PIXEL_FORMAT_RGB_888; 121448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith bufWidth = (mCropWidth + 1) & ~1; 122448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith bufHeight = (mCropHeight + 1) & ~1; 123448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith break; 124448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 125448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith case OMX_COLOR_Format32bitARGB8888: 12646b451fab7a26c501d4d6c87a354f70531c19d13David Smith case OMX_COLOR_Format32BitRGBA8888: 127448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith { 128448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith halFormat = HAL_PIXEL_FORMAT_RGBA_8888; 129448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith bufWidth = (mCropWidth + 1) & ~1; 130448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith bufHeight = (mCropHeight + 1) & ~1; 131448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith break; 132448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 133448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith default: 134448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith { 135448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith break; 136448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 1375e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber } 138448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 1395e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 140448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith if (halFormat == HAL_PIXEL_FORMAT_RGB_565) { 141448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith mConverter = new ColorConverter( 142448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith mColorFormat, OMX_COLOR_Format16bitRGB565); 143448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith CHECK(mConverter->isValid()); 14489e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber } 14589e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber 1461173118eace0e9e347cb007f0da817cee87579edGlenn Kasten CHECK(mNativeWindow != NULL); 1473571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber CHECK(mCropWidth > 0); 1483571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber CHECK(mCropHeight > 0); 1495daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK(mConverter == NULL || mConverter->isValid()); 1505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 1515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, 1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber native_window_set_usage( 1531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow.get(), 1545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN 155103487c0cb5c06f47225484486a98bc84745a059Andreas Huber | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP)); 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1579bc7af17974f448291a44912566ec7472a0d798bMathias Agopian CHECK_EQ(0, 1589bc7af17974f448291a44912566ec7472a0d798bMathias Agopian native_window_set_scaling_mode( 1599bc7af17974f448291a44912566ec7472a0d798bMathias Agopian mNativeWindow.get(), 1609bc7af17974f448291a44912566ec7472a0d798bMathias Agopian NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW)); 1619bc7af17974f448291a44912566ec7472a0d798bMathias Agopian 1625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber // Width must be multiple of 32??? 163475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu CHECK_EQ(0, native_window_set_buffers_dimensions( 1641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow.get(), 1655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufWidth, 166475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu bufHeight)); 167475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu CHECK_EQ(0, native_window_set_buffers_format( 168475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mNativeWindow.get(), 1695daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber halFormat)); 170ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 17125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar // NOTE: native window uses extended right-bottom coordinate 17225a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar android_native_rect_t crop; 17325a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar crop.left = mCropLeft; 17425a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar crop.top = mCropTop; 17525a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar crop.right = mCropRight + 1; 17625a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar crop.bottom = mCropBottom + 1; 17725a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]", 17825a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight); 17925a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar 18025a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop)); 18125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar 182475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu int32_t rotationDegrees; 183475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu if (!format->findInt32("rotation-degrees", &rotationDegrees)) { 184475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu rotationDegrees = 0; 185475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu } 186ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t transform; 187ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber switch (rotationDegrees) { 188ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 0: transform = 0; break; 189ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 90: transform = HAL_TRANSFORM_ROT_90; break; 190ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 180: transform = HAL_TRANSFORM_ROT_180; break; 191ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 270: transform = HAL_TRANSFORM_ROT_270; break; 192ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber default: transform = 0; break; 193ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 194ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 195475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu CHECK_EQ(0, native_window_set_buffers_transform( 196475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu mNativeWindow.get(), transform)); 1975e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber} 1985e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render( 200760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia const void *data, size_t size, int64_t timestampNs, 201475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu void* /*platformPrivate*/, const sp<AMessage>& format) { 202475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu resetFormatIfChanged(format); 203475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu 2048ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev ANativeWindowBuffer *buf; 2055de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber int err; 2061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), 2071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis &buf)) != 0) { 2085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Surface::dequeueBuffer returned error %d", err); 2095de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber return; 2105de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber } 2115de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber 2125daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 2135daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 2143571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber Rect bounds(mCropWidth, mCropHeight); 2155daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 2165daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber void *dst; 2175daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, mapper.lock( 2185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst)); 2195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 220448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith // TODO move the other conversions also into ColorConverter, and 221448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith // fix cropping issues (when mCropLeft/Top != 0 or mWidth != mCropWidth) 2225daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber if (mConverter) { 2235daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mConverter->convert( 224f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber data, 225f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber mWidth, mHeight, 2263571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber mCropLeft, mCropTop, mCropRight, mCropBottom, 227f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber dst, 228f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber buf->stride, buf->height, 2293571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 0, 0, mCropWidth - 1, mCropHeight - 1); 2303571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) { 231760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia if ((size_t)mWidth * mHeight * 3 / 2 > size) { 232760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia goto skip_copying; 233760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia } 2345e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber const uint8_t *src_y = (const uint8_t *)data; 235448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith const uint8_t *src_u = 236448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith (const uint8_t *)data + mWidth * mHeight; 2375e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2); 2385e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 2395e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber uint8_t *dst_y = (uint8_t *)dst; 2405e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t dst_y_size = buf->stride * buf->height; 2415e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t dst_c_stride = ALIGN(buf->stride / 2, 16); 2425e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t dst_c_size = dst_c_stride * buf->height / 2; 2435e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber uint8_t *dst_v = dst_y + dst_y_size; 2445e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber uint8_t *dst_u = dst_v + dst_c_size; 2455e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 2463571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber for (int y = 0; y < mCropHeight; ++y) { 2473571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber memcpy(dst_y, src_y, mCropWidth); 2485e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 2495e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber src_y += mWidth; 2505e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber dst_y += buf->stride; 2515e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber } 2525e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 2533571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber for (int y = 0; y < (mCropHeight + 1) / 2; ++y) { 2543571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber memcpy(dst_u, src_u, (mCropWidth + 1) / 2); 2553571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber memcpy(dst_v, src_v, (mCropWidth + 1) / 2); 2565e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 2575e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber src_u += mWidth / 2; 2585e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber src_v += mWidth / 2; 2595e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber dst_u += dst_c_stride; 2605e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber dst_v += dst_c_stride; 2615e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber } 2629578a90c214e430334b8696999f921290c35d067Lajos Molnar } else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar 2639578a90c214e430334b8696999f921290c35d067Lajos Molnar || mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { 264760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia if ((size_t)mWidth * mHeight * 3 / 2 > size) { 265760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia goto skip_copying; 266760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia } 267448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith const uint8_t *src_y = (const uint8_t *)data; 268448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith const uint8_t *src_uv = (const uint8_t *)data 269448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith + mWidth * (mHeight - mCropTop / 2); 2703571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 2713571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber uint8_t *dst_y = (uint8_t *)dst; 2723571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 2733571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber size_t dst_y_size = buf->stride * buf->height; 2743571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber size_t dst_c_stride = ALIGN(buf->stride / 2, 16); 2753571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber size_t dst_c_size = dst_c_stride * buf->height / 2; 2763571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber uint8_t *dst_v = dst_y + dst_y_size; 2773571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber uint8_t *dst_u = dst_v + dst_c_size; 2783571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 2793571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber for (int y = 0; y < mCropHeight; ++y) { 2803571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber memcpy(dst_y, src_y, mCropWidth); 2813571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 2823571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber src_y += mWidth; 2833571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber dst_y += buf->stride; 2843571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber } 2853571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 2863571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber for (int y = 0; y < (mCropHeight + 1) / 2; ++y) { 2873571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber size_t tmp = (mCropWidth + 1) / 2; 2883571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber for (size_t x = 0; x < tmp; ++x) { 2893571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber dst_u[x] = src_uv[2 * x]; 2903571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber dst_v[x] = src_uv[2 * x + 1]; 2913571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber } 2923571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber 2933571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber src_uv += mWidth; 2943571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber dst_u += dst_c_stride; 2953571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber dst_v += dst_c_stride; 2963571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber } 297448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } else if (mColorFormat == OMX_COLOR_Format24bitRGB888) { 298760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia if ((size_t)mWidth * mHeight * 3 > size) { 299760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia goto skip_copying; 300760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia } 301448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith uint8_t* srcPtr = (uint8_t*)data; 302448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith uint8_t* dstPtr = (uint8_t*)dst; 303448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith 304448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith for (size_t y = 0; y < (size_t)mCropHeight; ++y) { 305448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith memcpy(dstPtr, srcPtr, mCropWidth * 3); 306448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith srcPtr += mWidth * 3; 307448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith dstPtr += buf->stride * 3; 308448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 309448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } else if (mColorFormat == OMX_COLOR_Format32bitARGB8888) { 310760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia if ((size_t)mWidth * mHeight * 4 > size) { 311760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia goto skip_copying; 312760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia } 313448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith uint8_t *srcPtr, *dstPtr; 314448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith 315448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith for (size_t y = 0; y < (size_t)mCropHeight; ++y) { 316448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith srcPtr = (uint8_t*)data + mWidth * 4 * y; 317448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith dstPtr = (uint8_t*)dst + buf->stride * 4 * y; 318448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith for (size_t x = 0; x < (size_t)mCropWidth; ++x) { 319448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith uint8_t a = *srcPtr++; 320448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith for (size_t i = 0; i < 3; ++i) { // copy RGB 321448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith *dstPtr++ = *srcPtr++; 322448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 323448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith *dstPtr++ = a; // alpha last (ARGB to RGBA) 324448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 325448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } 32646b451fab7a26c501d4d6c87a354f70531c19d13David Smith } else if (mColorFormat == OMX_COLOR_Format32BitRGBA8888) { 327760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia if ((size_t)mWidth * mHeight * 4 > size) { 328760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia goto skip_copying; 329760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia } 33046b451fab7a26c501d4d6c87a354f70531c19d13David Smith uint8_t* srcPtr = (uint8_t*)data; 33146b451fab7a26c501d4d6c87a354f70531c19d13David Smith uint8_t* dstPtr = (uint8_t*)dst; 33246b451fab7a26c501d4d6c87a354f70531c19d13David Smith 33346b451fab7a26c501d4d6c87a354f70531c19d13David Smith for (size_t y = 0; y < (size_t)mCropHeight; ++y) { 33446b451fab7a26c501d4d6c87a354f70531c19d13David Smith memcpy(dstPtr, srcPtr, mCropWidth * 4); 33546b451fab7a26c501d4d6c87a354f70531c19d13David Smith srcPtr += mWidth * 4; 33646b451fab7a26c501d4d6c87a354f70531c19d13David Smith dstPtr += buf->stride * 4; 33746b451fab7a26c501d4d6c87a354f70531c19d13David Smith } 338448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith } else { 339448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith LOG_ALWAYS_FATAL("bad color format %#x", mColorFormat); 3405daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber } 3414265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber 342760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jiaskip_copying: 3435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, mapper.unlock(buf->handle)); 3444265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber 345908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar if ((err = native_window_set_buffers_timestamp(mNativeWindow.get(), 346908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar timestampNs)) != 0) { 347908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar ALOGW("Surface::set_buffers_timestamp returned error %d", err); 348908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar } 349908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar 3501e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf, 3511e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis -1)) != 0) { 3525ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Surface::queueBuffer returned error %d", err); 3535de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber } 3545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber buf = NULL; 3554265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber} 3564265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber 35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 358