allwinner_a64/android/hardware/aw/hwc2/threadResouce/hwc_submit_thread.cpp
2018-08-08 17:00:29 +08:00

177 lines
4.7 KiB
C++
Executable file

/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.
*/
#include <utils/Trace.h>
#include <cutils/log.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <cutils/uevent.h>
#include <system/graphics.h>
#include <cutils/properties.h>
#include "hwc.h"
int submitLayerToDisplay(Display_t *disp, LayerSubmit_t *submitLayer)
{
submitThread_t *myThread = disp->commitThread;
myThread->mutex->lock();
list_add_tail(&myThread->SubmitHead, &submitLayer->node);
myThread->cond->signal();
myThread->mutex->unlock();
return 0;
}
void inline submitDelayWork(Display_t *disp, LayerSubmit_t *submitLayer)
{
submitThread_t *myThread;
myThread = disp->commitThread;
myThread->delayDeal(disp, submitLayer);
submitLayerCachePut(submitLayer);
}
void* submitThreadLoop(void *display)
{
Display_t *disp;
submitThread_t *myThread;
struct listnode comHead, *commitHead, *node, *node2, *node3, *node4;
LayerSubmit_t *submitLayer = NULL, *preSubmit = NULL;
Layer_t *layer;
bool ctrlfps = 0;
disp = (Display_t *)display;
myThread = disp->commitThread;
commitHead = &comHead;
list_init(commitHead);
ALOGD("new a thread to commit the display:%d", disp->displayId);
setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
while (!myThread->stop) {
updateDebugFlags();
myThread->mutex->lock();
if (list_empty(&myThread->SubmitHead)) {
myThread->cond->waitRelative(*myThread->mutex, 16000000);
}
if(!disp->active) {
myThread->mutex->unlock();
continue;
}
showfps(disp);
ctrlfps = debugctrlfps();
if (list_empty(&myThread->SubmitHead)) {
myThread->mutex->unlock();
ALOGV("16ms not fresh");
continue;
}
memCtrlLimmitSet(disp, 2000000);
/* replace the list */
commitHead->next = myThread->SubmitHead.next;
myThread->SubmitHead.next->prev = commitHead;
commitHead->prev = myThread->SubmitHead.prev;
myThread->SubmitHead.prev->next = commitHead;
list_init(&myThread->SubmitHead);
myThread->mutex->unlock();
list_for_each_safe(node, node2, commitHead) {
submitLayer = node_to_item(node, LayerSubmit_t, node);
list_for_each_safe(node3, node4, &submitLayer->layerNode) {
layer = node_to_item(node3, Layer_t, node);
if (layer->acquireFence >= 0 && !ctrlfps) {
if (sync_wait((int)layer->acquireFence, 3000)) {
ALOGE("submit loop waite aquire fence err %d", layer->acquireFence);
/* dump fence */
}
}
/* gralloc unlock guarantee sync the buffer... */
/*if (checkSwWrite(layer))
syncLayerBuffer(layer);
*/
/* for debug */
dumpLayerZorder(layer, submitLayer->frameCount);
}
/* no block so may after waite fence, set up layer info to disp config2 info */
myThread->setupLayer(disp, submitLayer);
myThread->commitToDisplay(disp, submitLayer);
/* wait for vsync and a vsync send 1 frame ,
* so we wait for the last releasefence
*/
list_remove(&submitLayer->node);
if (preSubmit != NULL) {
/*sync_wait(preSubmit->sync.fd,
(disp->displayConfigList[disp->activeConfigId]->vsyncPeriod / 1000000 +1));
*/
submitDelayWork(disp, preSubmit);
}
myThread->diplayCount = submitLayer->frameCount;
myThread->SubmitCount = submitLayer->sync.count;
preSubmit = submitLayer;
if (ctrlfps)
usleep(20000);
}
}
if (preSubmit != NULL)
submitDelayWork(disp, preSubmit);
return NULL;
}
submitThread_t* initSubmitThread(Display_t *disp)
{
submitThread_t* myThread = (submitThread_t*)hwc_malloc(sizeof(submitThread_t));
if (myThread == NULL) {
ALOGE("malloc an err....");
return NULL;
}
myThread->mutex = new Mutex();
myThread->cond = new Condition();
list_init(&myThread->SubmitHead);
disp->commitThread = myThread;
pthread_create(&myThread->thread_id, NULL, submitThreadLoop, disp);
return myThread;
}
void deinitSubmitTread(Display_t *disp)
{
submitThread_t* myThread = disp->commitThread;
if(myThread== NULL)
return;
myThread->stop = 1;
pthread_join(myThread->thread_id, NULL);
delete(myThread->mutex);
delete(myThread->cond);
disp->commitThread = NULL;
clearList(&myThread->SubmitHead, 0);
hwc_free(myThread);
disp->commitThread = NULL;
}