Home | History | Annotate | Download | only in Scheduler
      1 /*
      2  * Copyright 2018 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 ATRACE_TAG ATRACE_TAG_GRAPHICS
     18 
     19 #include "DispSyncSource.h"
     20 
     21 #include <android-base/stringprintf.h>
     22 #include <utils/Trace.h>
     23 #include <mutex>
     24 
     25 #include "DispSync.h"
     26 #include "EventThread.h"
     27 
     28 namespace android {
     29 
     30 DispSyncSource::DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
     31                                const char* name)
     32       : mName(name),
     33         mTraceVsync(traceVsync),
     34         mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
     35         mVsyncEventLabel(base::StringPrintf("VSYNC-%s", name)),
     36         mDispSync(dispSync),
     37         mPhaseOffset(phaseOffset) {}
     38 
     39 void DispSyncSource::setVSyncEnabled(bool enable) {
     40     std::lock_guard lock(mVsyncMutex);
     41     if (enable) {
     42         status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
     43                                                    static_cast<DispSync::Callback*>(this),
     44                                                    mLastCallbackTime);
     45         if (err != NO_ERROR) {
     46             ALOGE("error registering vsync callback: %s (%d)", strerror(-err), err);
     47         }
     48         // ATRACE_INT(mVsyncOnLabel.c_str(), 1);
     49     } else {
     50         status_t err = mDispSync->removeEventListener(static_cast<DispSync::Callback*>(this),
     51                                                       &mLastCallbackTime);
     52         if (err != NO_ERROR) {
     53             ALOGE("error unregistering vsync callback: %s (%d)", strerror(-err), err);
     54         }
     55         // ATRACE_INT(mVsyncOnLabel.c_str(), 0);
     56     }
     57     mEnabled = enable;
     58 }
     59 
     60 void DispSyncSource::setCallback(VSyncSource::Callback* callback) {
     61     std::lock_guard lock(mCallbackMutex);
     62     mCallback = callback;
     63 }
     64 
     65 void DispSyncSource::setPhaseOffset(nsecs_t phaseOffset) {
     66     std::lock_guard lock(mVsyncMutex);
     67 
     68     // Normalize phaseOffset to [0, period)
     69     auto period = mDispSync->getPeriod();
     70     phaseOffset %= period;
     71     if (phaseOffset < 0) {
     72         // If we're here, then phaseOffset is in (-period, 0). After this
     73         // operation, it will be in (0, period)
     74         phaseOffset += period;
     75     }
     76     mPhaseOffset = phaseOffset;
     77 
     78     // If we're not enabled, we don't need to mess with the listeners
     79     if (!mEnabled) {
     80         return;
     81     }
     82 
     83     status_t err =
     84             mDispSync->changePhaseOffset(static_cast<DispSync::Callback*>(this), mPhaseOffset);
     85     if (err != NO_ERROR) {
     86         ALOGE("error changing vsync offset: %s (%d)", strerror(-err), err);
     87     }
     88 }
     89 
     90 void DispSyncSource::onDispSyncEvent(nsecs_t when) {
     91     VSyncSource::Callback* callback;
     92     {
     93         std::lock_guard lock(mCallbackMutex);
     94         callback = mCallback;
     95 
     96         if (mTraceVsync) {
     97             mValue = (mValue + 1) % 2;
     98             ATRACE_INT(mVsyncEventLabel.c_str(), mValue);
     99         }
    100     }
    101 
    102     if (callback != nullptr) {
    103         callback->onVSyncEvent(when);
    104     }
    105 }
    106 
    107 } // namespace android