SoftwareRenderer.cpp revision 103487c0cb5c06f47225484486a98bc84745a059
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 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/MemoryHeapBase.h> 2389e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber#include <binder/MemoryHeapPmem.h> 24f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h> 25f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/MetaData.h> 265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <surfaceflinger/Surface.h> 275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/android_native_buffer.h> 285daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h> 291173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <gui/ISurfaceTexture.h> 3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::SoftwareRenderer( 341173118eace0e9e347cb007f0da817cee87579edGlenn Kasten const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta) 35f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber : mConverter(NULL), 365daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mYUVMode(None), 371173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow(nativeWindow) { 38f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber int32_t tmp; 39f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(meta->findInt32(kKeyColorFormat, &tmp)); 40f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber mColorFormat = (OMX_COLOR_FORMATTYPE)tmp; 41f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 42f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(meta->findInt32(kKeyWidth, &mWidth)); 43f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(meta->findInt32(kKeyHeight, &mHeight)); 44f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 45f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber if (!meta->findRect( 46f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber kKeyCropRect, 47f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) { 48f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber mCropLeft = mCropTop = 0; 49f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber mCropRight = mWidth - 1; 50f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber mCropBottom = mHeight - 1; 51f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber } 52f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber 53f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber int32_t rotationDegrees; 54f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { 55f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber rotationDegrees = 0; 56f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber } 57a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber 585daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber int halFormat; 595e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t bufWidth, bufHeight; 605e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber switch (mColorFormat) { 625e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber case OMX_COLOR_FormatYUV420Planar: 635e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber { 645e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber halFormat = HAL_PIXEL_FORMAT_YV12; 655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufWidth = (mWidth + 1) & ~1; 665e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufHeight = (mHeight + 1) & ~1; 675e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber break; 685e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber } 695e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 705daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber default: 715daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber halFormat = HAL_PIXEL_FORMAT_RGB_565; 725e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufWidth = mWidth; 735e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufHeight = mHeight; 745daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 755daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mConverter = new ColorConverter( 765daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mColorFormat, OMX_COLOR_Format16bitRGB565); 775daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK(mConverter->isValid()); 785daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber break; 7989e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber } 8089e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber 811173118eace0e9e347cb007f0da817cee87579edGlenn Kasten CHECK(mNativeWindow != NULL); 82f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(mWidth > 0); 83f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber CHECK(mHeight > 0); 845daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK(mConverter == NULL || mConverter->isValid()); 855daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 865daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, 875daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber native_window_set_usage( 881173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow.get(), 895daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN 90103487c0cb5c06f47225484486a98bc84745a059Andreas Huber | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP)); 9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 925daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber // Width must be multiple of 32??? 935daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, native_window_set_buffers_geometry( 941173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow.get(), 955e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufWidth, 965e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber bufHeight, 975daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber halFormat)); 98ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 99ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber uint32_t transform; 100ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber switch (rotationDegrees) { 101ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 0: transform = 0; break; 102ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 90: transform = HAL_TRANSFORM_ROT_90; break; 103ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 180: transform = HAL_TRANSFORM_ROT_180; break; 104ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber case 270: transform = HAL_TRANSFORM_ROT_270; break; 105ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber default: transform = 0; break; 106ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 107ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber 108ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber if (transform) { 109ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber CHECK_EQ(0, native_window_set_buffers_transform( 1101173118eace0e9e347cb007f0da817cee87579edGlenn Kasten mNativeWindow.get(), transform)); 111ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber } 1125e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1135e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber android_native_rect_t crop; 1145e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber crop.left = mCropLeft; 1155e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber crop.top = mCropTop; 1165e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber crop.right = mCropRight + 1; 1175e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber crop.bottom = mCropBottom + 1; 1185e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1195e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop)); 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::~SoftwareRenderer() { 1235daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber delete mConverter; 1245daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mConverter = NULL; 1255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber} 1265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 1275e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huberstatic int ALIGN(int x, int y) { 1285e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber // y must be a power of 2. 1295e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber return (x + y - 1) & ~(y - 1); 1305e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber} 1315e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render( 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber const void *data, size_t size, void *platformPrivate) { 1348ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev ANativeWindowBuffer *buf; 1355de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber int err; 1361173118eace0e9e347cb007f0da817cee87579edGlenn Kasten if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) { 1375de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber LOGW("Surface::dequeueBuffer returned error %d", err); 1385de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber return; 1395de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber } 1405de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber 1411173118eace0e9e347cb007f0da817cee87579edGlenn Kasten CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf)); 1425daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 1435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber GraphicBufferMapper &mapper = GraphicBufferMapper::get(); 1445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 145f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber Rect bounds(mWidth, mHeight); 1465daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 1475daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber void *dst; 1485daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, mapper.lock( 1495daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst)); 1505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber 1515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber if (mConverter) { 1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber mConverter->convert( 153f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber data, 154f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber mWidth, mHeight, 1555e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 0, 0, mWidth - 1, mHeight - 1, 156f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber dst, 157f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber buf->stride, buf->height, 1585e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 0, 0, mWidth - 1, mHeight - 1); 1595daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber } else { 1605e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber CHECK_EQ(mColorFormat, OMX_COLOR_FormatYUV420Planar); 1615e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1625e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber const uint8_t *src_y = (const uint8_t *)data; 1635e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber const uint8_t *src_u = (const uint8_t *)data + mWidth * mHeight; 1645e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2); 1655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1665e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber uint8_t *dst_y = (uint8_t *)dst; 1675e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t dst_y_size = buf->stride * buf->height; 1685e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t dst_c_stride = ALIGN(buf->stride / 2, 16); 1695e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber size_t dst_c_size = dst_c_stride * buf->height / 2; 1705e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber uint8_t *dst_v = dst_y + dst_y_size; 1715e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber uint8_t *dst_u = dst_v + dst_c_size; 1725e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1735e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber for (int y = 0; y < mHeight; ++y) { 1745e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber memcpy(dst_y, src_y, mWidth); 1755e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1765e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber src_y += mWidth; 1775e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber dst_y += buf->stride; 1785e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber } 1795e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1805e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber for (int y = 0; y < (mHeight + 1) / 2; ++y) { 1815e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber memcpy(dst_u, src_u, (mWidth + 1) / 2); 1825e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber memcpy(dst_v, src_v, (mWidth + 1) / 2); 1835e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber 1845e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber src_u += mWidth / 2; 1855e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber src_v += mWidth / 2; 1865e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber dst_u += dst_c_stride; 1875e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber dst_v += dst_c_stride; 1885e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber } 1895daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber } 1904265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber 1915daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber CHECK_EQ(0, mapper.unlock(buf->handle)); 1924265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber 1931173118eace0e9e347cb007f0da817cee87579edGlenn Kasten if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) { 1945de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber LOGW("Surface::queueBuffer returned error %d", err); 1955de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber } 1965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber buf = NULL; 1974265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber} 1984265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 200