1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "QComHardwareRenderer" 19#include <utils/Log.h> 20 21#include "QComHardwareRenderer.h" 22 23#include <binder/MemoryHeapBase.h> 24#include <binder/MemoryHeapPmem.h> 25#include <media/stagefright/MediaDebug.h> 26#include <surfaceflinger/ISurface.h> 27 28namespace android { 29 30//////////////////////////////////////////////////////////////////////////////// 31 32typedef struct PLATFORM_PRIVATE_ENTRY 33{ 34 /* Entry type */ 35 uint32_t type; 36 37 /* Pointer to platform specific entry */ 38 void *entry; 39 40} PLATFORM_PRIVATE_ENTRY; 41 42typedef struct PLATFORM_PRIVATE_LIST 43{ 44 /* Number of entries */ 45 uint32_t nEntries; 46 47 /* Pointer to array of platform specific entries * 48 * Contiguous block of PLATFORM_PRIVATE_ENTRY elements */ 49 PLATFORM_PRIVATE_ENTRY *entryList; 50 51} PLATFORM_PRIVATE_LIST; 52 53// data structures for tunneling buffers 54typedef struct PLATFORM_PRIVATE_PMEM_INFO 55{ 56 /* pmem file descriptor */ 57 uint32_t pmem_fd; 58 uint32_t offset; 59 60} PLATFORM_PRIVATE_PMEM_INFO; 61 62#define PLATFORM_PRIVATE_PMEM 1 63 64QComHardwareRenderer::QComHardwareRenderer( 65 const sp<ISurface> &surface, 66 size_t displayWidth, size_t displayHeight, 67 size_t decodedWidth, size_t decodedHeight, 68 int32_t rotationDegrees) 69 : mISurface(surface), 70 mDisplayWidth(displayWidth), 71 mDisplayHeight(displayHeight), 72 mDecodedWidth(decodedWidth), 73 mDecodedHeight(decodedHeight), 74 mFrameSize((mDecodedWidth * mDecodedHeight * 3) / 2), 75 mRotationDegrees(rotationDegrees) { 76 CHECK(mISurface.get() != NULL); 77 CHECK(mDecodedWidth > 0); 78 CHECK(mDecodedHeight > 0); 79} 80 81QComHardwareRenderer::~QComHardwareRenderer() { 82 mISurface->unregisterBuffers(); 83} 84 85void QComHardwareRenderer::render( 86 const void *data, size_t size, void *platformPrivate) { 87 size_t offset; 88 if (!getOffset(platformPrivate, &offset)) { 89 return; 90 } 91 92 mISurface->postBuffer(offset); 93} 94 95bool QComHardwareRenderer::getOffset(void *platformPrivate, size_t *offset) { 96 *offset = 0; 97 98 PLATFORM_PRIVATE_LIST *list = (PLATFORM_PRIVATE_LIST *)platformPrivate; 99 for (uint32_t i = 0; i < list->nEntries; ++i) { 100 if (list->entryList[i].type != PLATFORM_PRIVATE_PMEM) { 101 continue; 102 } 103 104 PLATFORM_PRIVATE_PMEM_INFO *info = 105 (PLATFORM_PRIVATE_PMEM_INFO *)list->entryList[i].entry; 106 107 if (info != NULL) { 108 if (mMemoryHeap.get() == NULL) { 109 publishBuffers(info->pmem_fd); 110 } 111 112 if (mMemoryHeap.get() == NULL) { 113 return false; 114 } 115 116 *offset = info->offset; 117 118 return true; 119 } 120 } 121 122 return false; 123} 124 125void QComHardwareRenderer::publishBuffers(uint32_t pmem_fd) { 126 sp<MemoryHeapBase> master = 127 reinterpret_cast<MemoryHeapBase *>(pmem_fd); 128 129 master->setDevice("/dev/pmem"); 130 131 uint32_t heap_flags = master->getFlags() & MemoryHeapBase::NO_CACHING; 132 mMemoryHeap = new MemoryHeapPmem(master, heap_flags); 133 mMemoryHeap->slap(); 134 135 uint32_t orientation; 136 switch (mRotationDegrees) { 137 case 0: orientation = ISurface::BufferHeap::ROT_0; break; 138 case 90: orientation = ISurface::BufferHeap::ROT_90; break; 139 case 180: orientation = ISurface::BufferHeap::ROT_180; break; 140 case 270: orientation = ISurface::BufferHeap::ROT_270; break; 141 default: orientation = ISurface::BufferHeap::ROT_0; break; 142 } 143 144 ISurface::BufferHeap bufferHeap( 145 mDisplayWidth, mDisplayHeight, 146 mDecodedWidth, mDecodedHeight, 147 HAL_PIXEL_FORMAT_YCrCb_420_SP, 148 orientation, 0, 149 mMemoryHeap); 150 151 status_t err = mISurface->registerBuffers(bufferHeap); 152 if (err != OK) { 153 LOGE("ISurface::registerBuffers failed (err = %d)", err); 154 } 155} 156 157} // namespace android 158