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