714 lines
22 KiB
C++
Executable File
714 lines
22 KiB
C++
Executable File
/*
|
|
* Copyright 2018 Rockchip Electronics Co. LTD
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* author: xhr@rock-chips.com
|
|
* date: 2019/12/24
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "RTSubteSink"
|
|
|
|
#include "RTSubtitleSink.h"
|
|
#include "RTGraphicWindowApi.h"
|
|
#include "HdmiDefine.h"
|
|
|
|
#include <ui/DisplayMode.h>
|
|
#include <ui/DisplayState.h>
|
|
#include <input/DisplayViewport.h>
|
|
#include <utils/Log.h>
|
|
#include <cutils/properties.h> // for property_get
|
|
#include "RTChips.h"
|
|
|
|
using namespace ::android;
|
|
|
|
enum RkGpuType {
|
|
RK_GPU_G6110,
|
|
RK_GPU_MALI,
|
|
};
|
|
|
|
RTSubteSink::RTSubteSink() {
|
|
mInitialized = false;
|
|
mGpuType = RK_GPU_MALI;
|
|
|
|
// the gpu' ip of 3368 is g6110, and other chips is mali
|
|
RKChipInfo *chipInfo = getChipName();
|
|
if (chipInfo != NULL && (chipInfo->type == RK_CHIP_3368 || chipInfo->type == RK_CHIP_3368H)) {
|
|
mGpuType = RK_GPU_G6110;
|
|
}
|
|
}
|
|
|
|
RTSubteSink::~RTSubteSink() {
|
|
destroy();
|
|
}
|
|
|
|
void RTSubteSink::create(int renderType, int display) {
|
|
if (mInitialized) {
|
|
return;
|
|
}
|
|
|
|
mDisplay = EGL_NO_DISPLAY;
|
|
mEGLSurface = EGL_NO_SURFACE;
|
|
mContext = EGL_NO_CONTEXT;
|
|
|
|
mRenderType = renderType;
|
|
mClient = NULL;
|
|
mSurfaceControl = NULL;
|
|
mSubtitleZOrder = INT_MAX-2;
|
|
mSurfaceShow = false;
|
|
|
|
mDisplayMode = DISPLAY_ALL;
|
|
mDisplayDev = display;
|
|
mBindThread = false;
|
|
mHdmiMode = HDMI_3D_NONE;
|
|
|
|
createSubitleSurface();
|
|
if(mSurface != NULL) {
|
|
createEGLSurface();
|
|
}
|
|
|
|
if (mEGLSurface != EGL_NO_SURFACE) {
|
|
mInitialized = true;
|
|
show();
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::destroy() {
|
|
if (mInitialized) {
|
|
clean();
|
|
destoryEGLSurface();
|
|
}
|
|
|
|
if (mClient != NULL) {
|
|
mClient->dispose();
|
|
mClient = NULL;
|
|
}
|
|
|
|
mInitialized = false;
|
|
}
|
|
|
|
void RTSubteSink::createEGLSurface() {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if ((mSurfaceControl == NULL) || (mSurfaceControl->getSurface() == NULL)) {
|
|
return ;
|
|
}
|
|
|
|
EGLint defaultConfigAttribs[] = {
|
|
EGL_RED_SIZE, 8,
|
|
EGL_GREEN_SIZE, 8,
|
|
EGL_BLUE_SIZE, 8,
|
|
EGL_ALPHA_SIZE, 8,
|
|
EGL_DEPTH_SIZE, 0,
|
|
EGL_NONE
|
|
};
|
|
|
|
EGLint w, h;
|
|
EGLint numConfigs;
|
|
EGLConfig config;
|
|
|
|
mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
if (mDisplay == EGL_NO_DISPLAY) {
|
|
ALOGE("eglGetDisplay error: %#x\n", eglGetError());
|
|
}
|
|
|
|
EGLint majorVersion;
|
|
EGLint minorVersion;
|
|
eglInitialize(mDisplay, &majorVersion, &minorVersion);
|
|
eglChooseConfig(mDisplay,defaultConfigAttribs , &config, 1, &numConfigs);//attribs
|
|
mEGLSurface = eglCreateWindowSurface(mDisplay, config,mSurface.get(), NULL);
|
|
if (mEGLSurface == EGL_NO_SURFACE) {
|
|
ALOGE("eglCreateWindowSurface error: %#x\n", eglGetError());
|
|
return;
|
|
}
|
|
|
|
mContext = eglCreateContext(mDisplay, config, EGL_NO_CONTEXT, NULL);
|
|
if (mContext == EGL_NO_CONTEXT) {
|
|
ALOGE("eglCreateWindowSurface error: %#x\n", eglGetError());
|
|
return;
|
|
}
|
|
|
|
eglQuerySurface(mDisplay, mEGLSurface, EGL_WIDTH, &w);
|
|
eglQuerySurface(mDisplay, mEGLSurface, EGL_HEIGHT, &h);
|
|
|
|
mRect.width = w;
|
|
mRect.height = h;
|
|
ALOGD("create egl surface(width=%d, height=%d)", w, h);
|
|
}
|
|
|
|
void RTSubteSink::destoryEGLSurface() {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if(mRenderType == RENDER_RGA) {
|
|
return ;
|
|
}
|
|
ALOGD("destoryEGLSurface");
|
|
if (mClient != NULL) {
|
|
mClient->dispose();
|
|
}
|
|
|
|
if (mDisplay != EGL_NO_DISPLAY) {
|
|
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
}
|
|
|
|
if (mContext != EGL_NO_CONTEXT) {
|
|
eglDestroyContext(mDisplay, mContext);
|
|
}
|
|
|
|
if (mEGLSurface != EGL_NO_SURFACE) {
|
|
eglDestroySurface(mDisplay, mEGLSurface);
|
|
}
|
|
|
|
if (mSurface != NULL) {
|
|
mSurface.clear();
|
|
mSurface = NULL;
|
|
}
|
|
|
|
if (mDisplay != EGL_NO_DISPLAY) {
|
|
eglTerminate(mDisplay);
|
|
}
|
|
|
|
mContext = EGL_NO_CONTEXT;
|
|
mEGLSurface = EGL_NO_SURFACE;
|
|
mDisplay = EGL_NO_DISPLAY;
|
|
}
|
|
|
|
bool RTSubteSink::bindSurfaceToThread() {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if (mRenderType == RENDER_RGA) {
|
|
return false;
|
|
}
|
|
if (mEGLSurface != EGL_NO_SURFACE) {
|
|
if (eglMakeCurrent(mDisplay, mEGLSurface, mEGLSurface, mContext) == EGL_FALSE) {
|
|
ALOGD("failed to bind surface to thread");
|
|
return false;
|
|
}
|
|
mBindThread = true;
|
|
ALOGD("succeed to bind surface to thread");
|
|
return true;
|
|
}
|
|
ALOGD("failed to bind surface to thread");
|
|
return false;
|
|
}
|
|
|
|
void RTSubteSink::initScene() {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if ((mRenderType == RENDER_GPU) && (mEGLSurface != EGL_NO_SURFACE)) {
|
|
glDisable(GL_DITHER);
|
|
glEnable(GL_CULL_FACE);
|
|
glViewport(0, 0, mRect.width, mRect.height);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glOrthof(0,mRect.width,0,mRect.height,0,1);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::showScene() {
|
|
if (!mInitialized) {
|
|
return;
|
|
}
|
|
|
|
if (mRenderType == RENDER_GPU) {
|
|
if (mEGLSurface != EGL_NO_SURFACE) {
|
|
eglSwapBuffers(mDisplay, mEGLSurface);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::render(RTSubFrame *frame) {
|
|
if (!mInitialized) {
|
|
return;
|
|
}
|
|
|
|
if(!mBindThread) {
|
|
bindSurfaceToThread();
|
|
}
|
|
if(mRenderType == RENDER_GPU) {
|
|
gpuRender(frame);
|
|
} else {
|
|
ALOGE("render: not support");
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::gpuRender(RTSubFrame *frame) {
|
|
if (mEGLSurface == EGL_NO_SURFACE) {
|
|
return;
|
|
}
|
|
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if (frame != NULL && frame->data != NULL) {
|
|
GLuint texture;
|
|
int x = frame->x;
|
|
int y = frame->y;
|
|
int width = frame->width;
|
|
int height = frame->height;
|
|
|
|
initTexture(frame->data,width,height,texture);
|
|
float widthScale = ((float)mRect.width/(float)frame->subWidth);
|
|
float heightScale = ((float)mRect.height/(float)frame->subHeight);
|
|
|
|
#if 0
|
|
if (mHdmiManager != NULL) {
|
|
mode = mHdmiManager->getCurrentMode();
|
|
}
|
|
#endif
|
|
if (mHdmiMode == HDMI_3D_SIDE_BY_SIDE_HALT) {
|
|
widthScale = widthScale/2;
|
|
} else if (mHdmiMode == HDMI_3D_TOP_BOTTOM) {
|
|
heightScale = heightScale/2;
|
|
}
|
|
|
|
float realWidth = ((float)width)*widthScale;
|
|
float realHight = ((float)height)*heightScale;
|
|
float realX = ((float)x)*widthScale;
|
|
float realY = ((float)(frame->subHeight - y))*heightScale-realHight;
|
|
|
|
if (realY < 0) {
|
|
realY = 20;
|
|
if (realX*2 + realWidth > mRect.width) {
|
|
realX = (mRect.width - realWidth) / 2;
|
|
}
|
|
|
|
if (y + height > frame->subHeight) {
|
|
realHight = height * (widthScale >= 2 ? 2 : 1);
|
|
}
|
|
ALOGD("gpuRender origin coordinate: x = %d,y = %d,width = %d,height = %d", x, y, width, height);
|
|
}
|
|
GLfloat texCoords[] = {
|
|
0, 1,
|
|
1.0, 1,
|
|
1.0, 0,
|
|
0, 0
|
|
};
|
|
|
|
bool changed = false;
|
|
if (frame->needcrop && (mDisplayMode == DISPLAY_LEFT_HALF)) {
|
|
float texX = 1.0f;
|
|
if ((realX < (mRect.width/2)) && ((realX+realWidth) > (mRect.width/2))) {
|
|
texX = (((float)(mRect.width/2)-realX))/realWidth;
|
|
realX *= 2;
|
|
realWidth *= 2;
|
|
changed = true;
|
|
}
|
|
texCoords[2] = texX;//0.5;
|
|
texCoords[4] = texX;//0.5;
|
|
} else if (frame->needcrop && (mDisplayMode == DISPLAY_TOP_HALF)) {
|
|
float texY= 1.0f;
|
|
if ((realY < (mRect.height/2)) && ((realY+realHight) > (mRect.height/2))) {
|
|
texY = 0.5f;
|
|
changed = true;
|
|
}
|
|
texCoords[1] = texY;
|
|
texCoords[3] = texY;
|
|
}
|
|
|
|
const GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
|
|
int nelem = sizeof(indices)/sizeof(indices[0]);
|
|
|
|
// 2D
|
|
if (mHdmiMode == HDMI_3D_NONE) {
|
|
GLfloat vertices[] = {
|
|
realX, realY, 0,
|
|
realX+realWidth, realY, 0,
|
|
realX+realWidth, realY+realHight, 0,
|
|
realX, realY+realHight, 0
|
|
};
|
|
|
|
if (changed) {
|
|
if (mDisplayMode == DISPLAY_LEFT_HALF) {
|
|
vertices[3] = (realX+realWidth)/2;
|
|
vertices[6] = (realX+realWidth)/2;
|
|
} else if (mDisplayMode == DISPLAY_TOP_HALF) {
|
|
vertices[7] = realY + realHight/2;
|
|
vertices[10] = realY + realHight/2;
|
|
}
|
|
}
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, vertices);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
|
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
|
|
} else if (mHdmiMode == HDMI_3D_SIDE_BY_SIDE_HALT) {
|
|
float realLeftX = ((float)x)*widthScale;
|
|
float realRightX = ((float)x)*widthScale+mRect.width/2;
|
|
|
|
const GLfloat leftVertices[] = {
|
|
realLeftX, realY, 0,
|
|
realLeftX+realWidth, realY, 0,
|
|
realLeftX+realWidth, realY+realHight, 0,
|
|
realLeftX, realY+realHight, 0
|
|
};
|
|
|
|
const GLfloat RightVertices[] = {
|
|
realRightX, realY, 0,
|
|
realRightX+realWidth, realY, 0,
|
|
realRightX+realWidth, realY+realHight, 0,
|
|
realRightX, realY+realHight, 0
|
|
};
|
|
|
|
// left
|
|
glVertexPointer(3, GL_FLOAT, 0, leftVertices);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
|
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
|
|
|
|
// right
|
|
glVertexPointer(3, GL_FLOAT, 0, RightVertices);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
|
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
|
|
} else if (mHdmiMode == HDMI_3D_TOP_BOTTOM) {
|
|
float realTopY = (float)mRect.height/2 - ((float)y)*heightScale - realHight;
|
|
float realBottomY = (float)mRect.height - ((float)y)*heightScale - realHight;
|
|
const GLfloat topVertices[] = {
|
|
realX, realTopY, 0,
|
|
realX+realWidth, realTopY, 0,
|
|
realX+realWidth, realTopY+realHight, 0,
|
|
realX, realTopY+realHight, 0
|
|
};
|
|
|
|
const GLfloat bottomVertices[] = {
|
|
realX, realBottomY, 0,
|
|
realX+realWidth, realBottomY, 0,
|
|
realX+realWidth, realBottomY+realHight, 0,
|
|
realX, realBottomY+realHight, 0
|
|
};
|
|
|
|
// top
|
|
glVertexPointer(3, GL_FLOAT, 0, topVertices);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
|
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
|
|
|
|
// bottom
|
|
glVertexPointer(3, GL_FLOAT, 0, bottomVertices);
|
|
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
|
|
glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
|
|
}
|
|
|
|
glDeleteTextures(1, &texture);
|
|
}
|
|
}
|
|
|
|
int RTSubteSink::initTexture(void* data,int width,int height,GLuint& texture) {
|
|
GLint crop[4] = { 0, height, width, -height };
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
glGenTextures(1, &texture);
|
|
glBindTexture(GL_TEXTURE_2D, texture);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
|
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
|
|
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
|
|
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
|
|
|
if (RK_GPU_G6110 == mGpuType) {
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
void RTSubteSink::clean() {
|
|
if (!mInitialized) {
|
|
return;
|
|
}
|
|
|
|
if (mRenderType == RENDER_RGA) {
|
|
ANativeWindow_Buffer mSurfaceInfo;
|
|
unsigned char* mSurfaceBuf = NULL;
|
|
|
|
ARect dirtyregion;
|
|
dirtyregion.left = 0;
|
|
dirtyregion.right = 0x3fff;
|
|
dirtyregion.top = 0;
|
|
dirtyregion.bottom = 0x3fff;
|
|
|
|
int status = mSurface->lock(&mSurfaceInfo, &dirtyregion);
|
|
if (status != 0) {
|
|
return ;
|
|
}
|
|
|
|
mSurfaceBuf = reinterpret_cast<unsigned char*>(mSurfaceInfo.bits);
|
|
if (mSurfaceBuf != NULL) {
|
|
memset(mSurfaceBuf,0, mSurfaceInfo.width* mSurfaceInfo.height*sizeof(int));
|
|
}
|
|
|
|
mSurface->unlockAndPost();
|
|
} else if (mRenderType == RENDER_GPU) {
|
|
if (mEGLSurface != EGL_NO_SURFACE) {
|
|
initScene();
|
|
eglSwapBuffers(mDisplay, mEGLSurface);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::show() {
|
|
if (!mInitialized || mSurfaceShow) {
|
|
return;
|
|
}
|
|
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if (mSurfaceControl != NULL) {
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::ShowSurface(mSurfaceControl, &t);
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
mSurfaceShow = true;
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::hide() {
|
|
if (!mInitialized || !mSurfaceShow) {
|
|
return;
|
|
}
|
|
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if (mSurfaceControl != NULL) {
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::HideSurface(mSurfaceControl, &t);
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
mSurfaceShow = false;
|
|
}
|
|
}
|
|
|
|
bool RTSubteSink::isShowing() {
|
|
return mSurfaceShow;
|
|
}
|
|
|
|
void RTSubteSink::createSubitleSurface() {
|
|
if(mClient == NULL) {
|
|
mClient = new SurfaceComposerClient();
|
|
if (mClient != NULL) {
|
|
ui::DisplayMode mode;
|
|
ui::DisplayState state;
|
|
getSurfaceMaxWidthAndHeight(mode,state, 0);
|
|
// create the native surface
|
|
mSurfaceControl = mClient->createSurface(String8("SubtitleSurface"),mode.resolution.getWidth(),mode.resolution.getHeight(),PIXEL_FORMAT_RGBA_8888);
|
|
if (mSurfaceControl != NULL) {
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::SetSurfaceLayer(mSurfaceControl, &t, mSubtitleZOrder);
|
|
GraphicWindowApi::SetSurfacePosition(mSurfaceControl, &t, 0, 0);
|
|
GraphicWindowApi::SetSurfaceSize(mSurfaceControl, &t,mode.resolution.getWidth(),mode.resolution.getHeight());
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
mSurface = mSurfaceControl->getSurface();
|
|
|
|
mRect.x = 0;
|
|
mRect.y = 0;
|
|
mRect.width = mode.resolution.getWidth();
|
|
mRect.height = mode.resolution.getHeight();
|
|
mRect.rotation = (int)state.orientation;
|
|
} else {
|
|
ALOGE("createSubitleSurface:mSurfaceControl == NULL");
|
|
}
|
|
} else {
|
|
ALOGE("createSubitleSurface:mClient == NULL");
|
|
}
|
|
}
|
|
}
|
|
|
|
int RTSubteSink::setLayerStack(int display) {
|
|
int status = -1;
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if (mSurfaceControl != NULL) {
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::SetSurfaceLayerStack(mSurfaceControl, &t, display);
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
status = 0;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
int RTSubteSink::setSubtitleSurfaceZOrder(int order) {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if(mSubtitleZOrder != order) {
|
|
if (mClient != NULL && mSurfaceControl != NULL) {
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::SetSurfaceLayer(mSurfaceControl, &t, order);
|
|
mSubtitleZOrder = order;
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int RTSubteSink::setSubtitleSurfacePosition(int x,int y,int width,int height) {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
if (mClient != NULL && mSurfaceControl != NULL) {
|
|
ui::DisplayMode mode;
|
|
ui::DisplayState state;
|
|
getSurfaceMaxWidthAndHeight(mode,state,0);
|
|
|
|
int maxWidth = mode.resolution.getWidth();
|
|
int maxHeight = mode.resolution.getHeight();
|
|
maxWidth = (maxWidth>=width)?width:maxWidth;
|
|
maxHeight = (maxHeight>=height)?height:maxHeight;
|
|
|
|
if((x != mRect.x) || (y != mRect.y) || (maxWidth != mRect.width) || (maxHeight != mRect.height)) {
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::SetSurfacePosition(mSurfaceControl, &t, x, y);
|
|
GraphicWindowApi::SetSurfaceSize(mSurfaceControl, &t, maxWidth, maxHeight);
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
|
|
mRect.x = x;
|
|
mRect.y = y;
|
|
mRect.width = maxWidth;
|
|
mRect.height= maxHeight;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void RTSubteSink::setSubtitleSurfaceVisibility(int visible) {
|
|
if (visible == 1) {
|
|
show();
|
|
} else {
|
|
hide();
|
|
}
|
|
}
|
|
|
|
void RTSubteSink::displayPgsSubtitle() {
|
|
|
|
}
|
|
|
|
SurfaceRect& RTSubteSink::getSurfaceRect() {
|
|
return mRect;
|
|
}
|
|
|
|
int RTSubteSink::getSurfaceZOrder() {
|
|
return mSubtitleZOrder;
|
|
}
|
|
|
|
|
|
void RTSubteSink::setSubtitleMode(int mode) {
|
|
mDisplayMode = mode;
|
|
}
|
|
|
|
void RTSubteSink::setHdmiMode(int mode) {
|
|
mHdmiMode = mode;
|
|
}
|
|
|
|
bool RTSubteSink::checkRotation() {
|
|
Mutex::Autolock autoLock(mRenderLock);
|
|
ui::DisplayMode mode;
|
|
ui::DisplayState state;
|
|
getSurfaceMaxWidthAndHeight(mode, state, mDisplayDev);
|
|
if((mode.resolution.getWidth() != mRect.width) || (mode.resolution.getHeight() != mRect.height) || ((int)state.orientation != mRect.rotation)){
|
|
mRect.width = mode.resolution.getWidth();
|
|
mRect.height = mode.resolution.getHeight();
|
|
mRect.rotation = (int)state.orientation;
|
|
|
|
// if rotation is happend, must set new position and size
|
|
GraphicWindowApi::OpenSurfaceTransaction();
|
|
Transaction t;
|
|
GraphicWindowApi::SetSurfacePosition(mSurfaceControl, &t, mRect.x, mRect.y);
|
|
GraphicWindowApi::SetSurfaceSize(mSurfaceControl, &t, mRect.width, mRect.height);
|
|
GraphicWindowApi::CloseSurfaceTransaction(&t);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void RTSubteSink::getSurfaceMaxWidthAndHeight(ui::DisplayMode& mode, ui::DisplayState& state, int displayId)
|
|
{
|
|
int width = 1920;
|
|
int height = 1080;
|
|
int orientation = DISPLAY_ORIENTATION_0;
|
|
status_t err;
|
|
|
|
// set default value
|
|
mode.resolution.set(width,height);
|
|
state.orientation = (android::ui::Rotation)orientation;
|
|
|
|
if(0 /*ISurfaceComposer::eDisplayIdMain*/ != displayId && 1 /*ISurfaceComposer::eDisplayIdHdmi*/ != displayId){
|
|
ALOGE("getSurfaceMaxWidthAndHeight: displayId = %d in not suppport, set default widht = 1920,height = 1080", displayId);
|
|
return ;
|
|
}
|
|
// sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(displayId));
|
|
|
|
const auto display = SurfaceComposerClient::getInternalDisplayToken();
|
|
if(display == nullptr){
|
|
ALOGE("error: no display");
|
|
return;
|
|
}
|
|
|
|
err = SurfaceComposerClient::getDisplayState(display, &state);
|
|
if(err != NO_ERROR){
|
|
ALOGE("error: unable to get display state");
|
|
return;
|
|
}
|
|
|
|
err = SurfaceComposerClient::getActiveDisplayMode(display, &mode);
|
|
if(err != NO_ERROR){
|
|
ALOGE("error: unable to get display mode");
|
|
return;
|
|
}
|
|
|
|
char value[PROPERTY_VALUE_MAX];
|
|
if((state.orientation == (android::ui::Rotation)DISPLAY_ORIENTATION_90) || (state.orientation == (android::ui::Rotation)DISPLAY_ORIENTATION_270)){
|
|
width = mode.resolution.getWidth();
|
|
height = mode.resolution.getHeight();
|
|
orientation = (int)state.orientation;
|
|
}else{
|
|
property_get("ro.sf.fakerotation", value, "false");
|
|
if (strcmp(value,"true") == 0) {
|
|
property_get("ro.sf.hwrotation", value, "0");
|
|
if ((strcmp(value,"90") == 0) || (strcmp(value,"270") == 0)) {
|
|
width = mode.resolution.getWidth();
|
|
height = mode.resolution.getHeight();
|
|
orientation = (strcmp(value,"90") == 0)?DISPLAY_ORIENTATION_90:DISPLAY_ORIENTATION_270;
|
|
} else {
|
|
width = mode.resolution.getWidth();
|
|
height = mode.resolution.getHeight();
|
|
}
|
|
} else {
|
|
width = mode.resolution.getWidth();
|
|
height = mode.resolution.getHeight();
|
|
}
|
|
}
|
|
|
|
if(0 /*ISurfaceComposer::eDisplayIdMain*/ == displayId){
|
|
property_get("persist.sys.display.policy", value, "");
|
|
if (strcasecmp(value,"auto") == 0) {
|
|
property_get("sys.fb.cursize", value, "1280x720");
|
|
sscanf(value,"%dx%d",&width,&height);
|
|
}
|
|
}
|
|
|
|
mode.resolution.set(width,height);
|
|
state.orientation = (android::ui::Rotation)orientation;
|
|
}
|
|
|