/* * Copyright (C) 2014 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 "tests/common/TestContext.h" #include <cutils/trace.h> namespace android { namespace uirenderer { namespace test { static const int IDENT_DISPLAYEVENT = 1; static android::DisplayInfo DUMMY_DISPLAY{ 1080, // w 1920, // h 320.0, // xdpi 320.0, // ydpi 60.0, // fps 2.0, // density 0, // orientation false, // secure? 0, // appVsyncOffset 0, // presentationDeadline }; DisplayInfo getInternalDisplay() { #if !HWUI_NULL_GPU DisplayInfo display; const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken(); LOG_ALWAYS_FATAL_IF(token == nullptr, "Failed to get display info because internal display is disconnected\n"); status_t status = SurfaceComposerClient::getDisplayInfo(token, &display); LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n"); return display; #else return DUMMY_DISPLAY; #endif } // Initialize to a dummy default android::DisplayInfo gDisplay = DUMMY_DISPLAY; TestContext::TestContext() { mLooper = new Looper(true); mSurfaceComposerClient = new SurfaceComposerClient(); mLooper->addFd(mDisplayEventReceiver.getFd(), IDENT_DISPLAYEVENT, Looper::EVENT_INPUT, nullptr, nullptr); } TestContext::~TestContext() {} sp<Surface> TestContext::surface() { if (!mSurface.get()) { createSurface(); } return mSurface; } void TestContext::createSurface() { if (mRenderOffscreen) { createOffscreenSurface(); } else { createWindowSurface(); } } void TestContext::createWindowSurface() { mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"), gDisplay.w, gDisplay.h, PIXEL_FORMAT_RGBX_8888); SurfaceComposerClient::Transaction t; t.setLayer(mSurfaceControl, 0x7FFFFFF).show(mSurfaceControl).apply(); mSurface = mSurfaceControl->getSurface(); } void TestContext::createOffscreenSurface() { sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer); producer->setMaxDequeuedBufferCount(3); producer->setAsyncMode(true); mConsumer = new BufferItemConsumer(consumer, GRALLOC_USAGE_HW_COMPOSER, 4); mConsumer->setDefaultBufferSize(gDisplay.w, gDisplay.h); mSurface = new Surface(producer); } void TestContext::waitForVsync() { // Hacky fix for not getting sysprop change callbacks // We just poll the sysprop in vsync since it's when the UI thread is // "idle" and shouldn't burn too much time atrace_update_tags(); if (mConsumer.get()) { BufferItem buffer; if (mConsumer->acquireBuffer(&buffer, 0, false) == OK) { // We assume the producer is internally ordered enough such that // it is unneccessary to set a release fence mConsumer->releaseBuffer(buffer); } // We running free, go go go! return; } #if !HWUI_NULL_GPU // Request vsync mDisplayEventReceiver.requestNextVsync(); // Wait mLooper->pollOnce(-1); // Drain it DisplayEventReceiver::Event buf[100]; while (mDisplayEventReceiver.getEvents(buf, 100) > 0) { } #endif } } // namespace test } // namespace uirenderer } // namespace android