/* * Copyright 2016 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. */ #ifndef ANDROID_SF_COMPOSER_HAL_H #define ANDROID_SF_COMPOSER_HAL_H #include <memory> #include <string> #include <unordered_map> #include <utility> #include <vector> #include <android/frameworks/vr/composer/1.0/IVrComposerClient.h> #include <android/hardware/graphics/composer/2.1/IComposer.h> #include <utils/StrongPointer.h> #include <IComposerCommandBuffer.h> namespace android { namespace Hwc2 { using android::frameworks::vr::composer::V1_0::IVrComposerClient; using android::hardware::graphics::common::V1_0::ColorMode; using android::hardware::graphics::common::V1_0::ColorTransform; using android::hardware::graphics::common::V1_0::Dataspace; using android::hardware::graphics::common::V1_0::Hdr; using android::hardware::graphics::common::V1_0::PixelFormat; using android::hardware::graphics::common::V1_0::Transform; using android::hardware::graphics::composer::V2_1::IComposer; using android::hardware::graphics::composer::V2_1::IComposerCallback; using android::hardware::graphics::composer::V2_1::IComposerClient; using android::hardware::graphics::composer::V2_1::Error; using android::hardware::graphics::composer::V2_1::Display; using android::hardware::graphics::composer::V2_1::Layer; using android::hardware::graphics::composer::V2_1::Config; using android::hardware::graphics::composer::V2_1::CommandWriterBase; using android::hardware::graphics::composer::V2_1::CommandReaderBase; using android::hardware::kSynchronizedReadWrite; using android::hardware::MessageQueue; using android::hardware::MQDescriptorSync; using android::hardware::hidl_vec; using android::hardware::hidl_handle; class CommandReader : public CommandReaderBase { public: ~CommandReader(); // Parse and execute commands from the command queue. The commands are // actually return values from the server and will be saved in ReturnData. Error parse(); // Get and clear saved errors. struct CommandError { uint32_t location; Error error; }; std::vector<CommandError> takeErrors(); bool hasChanges(Display display, uint32_t* outNumChangedCompositionTypes, uint32_t* outNumLayerRequestMasks) const; // Get and clear saved changed composition types. void takeChangedCompositionTypes(Display display, std::vector<Layer>* outLayers, std::vector<IComposerClient::Composition>* outTypes); // Get and clear saved display requests. void takeDisplayRequests(Display display, uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers, std::vector<uint32_t>* outLayerRequestMasks); // Get and clear saved release fences. void takeReleaseFences(Display display, std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences); // Get and clear saved present fence. void takePresentFence(Display display, int* outPresentFence); // Get what stage succeeded during PresentOrValidate: Present or Validate void takePresentOrValidateStage(Display display, uint32_t * state); private: void resetData(); bool parseSelectDisplay(uint16_t length); bool parseSetError(uint16_t length); bool parseSetChangedCompositionTypes(uint16_t length); bool parseSetDisplayRequests(uint16_t length); bool parseSetPresentFence(uint16_t length); bool parseSetReleaseFences(uint16_t length); bool parseSetPresentOrValidateDisplayResult(uint16_t length); struct ReturnData { uint32_t displayRequests = 0; std::vector<Layer> changedLayers; std::vector<IComposerClient::Composition> compositionTypes; std::vector<Layer> requestedLayers; std::vector<uint32_t> requestMasks; int presentFence = -1; std::vector<Layer> releasedLayers; std::vector<int> releaseFences; uint32_t presentOrValidateState; }; std::vector<CommandError> mErrors; std::unordered_map<Display, ReturnData> mReturnData; // When SELECT_DISPLAY is parsed, this is updated to point to the // display's return data in mReturnData. We use it to avoid repeated // map lookups. ReturnData* mCurrentReturnData; }; // Composer is a wrapper to IComposer, a proxy to server-side composer. class Composer { public: Composer(bool useVrComposer); std::vector<IComposer::Capability> getCapabilities(); std::string dumpDebugInfo(); void registerCallback(const sp<IComposerCallback>& callback); // Reset all pending commands in the command buffer. Useful if you want to // skip a frame but have already queued some commands. void resetCommands(); uint32_t getMaxVirtualDisplayCount(); bool isUsingVrComposer() const { return mIsUsingVrComposer; } Error createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, Display* outDisplay); Error destroyVirtualDisplay(Display display); Error acceptDisplayChanges(Display display); Error createLayer(Display display, Layer* outLayer); Error destroyLayer(Display display, Layer layer); Error getActiveConfig(Display display, Config* outConfig); Error getChangedCompositionTypes(Display display, std::vector<Layer>* outLayers, std::vector<IComposerClient::Composition>* outTypes); Error getColorModes(Display display, std::vector<ColorMode>* outModes); Error getDisplayAttribute(Display display, Config config, IComposerClient::Attribute attribute, int32_t* outValue); Error getDisplayConfigs(Display display, std::vector<Config>* outConfigs); Error getDisplayName(Display display, std::string* outName); Error getDisplayRequests(Display display, uint32_t* outDisplayRequestMask, std::vector<Layer>* outLayers, std::vector<uint32_t>* outLayerRequestMasks); Error getDisplayType(Display display, IComposerClient::DisplayType* outType); Error getDozeSupport(Display display, bool* outSupport); Error getHdrCapabilities(Display display, std::vector<Hdr>* outTypes, float* outMaxLuminance, float* outMaxAverageLuminance, float* outMinLuminance); Error getReleaseFences(Display display, std::vector<Layer>* outLayers, std::vector<int>* outReleaseFences); Error presentDisplay(Display display, int* outPresentFence); Error setActiveConfig(Display display, Config config); /* * The composer caches client targets internally. When target is nullptr, * the composer uses slot to look up the client target from its cache. * When target is not nullptr, the cache is updated with the new target. */ Error setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, const std::vector<IComposerClient::Rect>& damage); Error setColorMode(Display display, ColorMode mode); Error setColorTransform(Display display, const float* matrix, ColorTransform hint); Error setOutputBuffer(Display display, const native_handle_t* buffer, int releaseFence); Error setPowerMode(Display display, IComposerClient::PowerMode mode); Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled); Error setClientTargetSlotCount(Display display); Error validateDisplay(Display display, uint32_t* outNumTypes, uint32_t* outNumRequests); Error presentOrValidateDisplay(Display display, uint32_t* outNumTypes, uint32_t* outNumRequests, int* outPresentFence, uint32_t* state); Error setCursorPosition(Display display, Layer layer, int32_t x, int32_t y); /* see setClientTarget for the purpose of slot */ Error setLayerBuffer(Display display, Layer layer, uint32_t slot, const sp<GraphicBuffer>& buffer, int acquireFence); Error setLayerSurfaceDamage(Display display, Layer layer, const std::vector<IComposerClient::Rect>& damage); Error setLayerBlendMode(Display display, Layer layer, IComposerClient::BlendMode mode); Error setLayerColor(Display display, Layer layer, const IComposerClient::Color& color); Error setLayerCompositionType(Display display, Layer layer, IComposerClient::Composition type); Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace); Error setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame); Error setLayerPlaneAlpha(Display display, Layer layer, float alpha); Error setLayerSidebandStream(Display display, Layer layer, const native_handle_t* stream); Error setLayerSourceCrop(Display display, Layer layer, const IComposerClient::FRect& crop); Error setLayerTransform(Display display, Layer layer, Transform transform); Error setLayerVisibleRegion(Display display, Layer layer, const std::vector<IComposerClient::Rect>& visible); Error setLayerZOrder(Display display, Layer layer, uint32_t z); Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId); private: class CommandWriter : public CommandWriterBase { public: CommandWriter(uint32_t initialMaxSize); ~CommandWriter() override; void setLayerInfo(uint32_t type, uint32_t appId); void setClientTargetMetadata( const IVrComposerClient::BufferMetadata& metadata); void setLayerBufferMetadata( const IVrComposerClient::BufferMetadata& metadata); private: void writeBufferMetadata( const IVrComposerClient::BufferMetadata& metadata); }; // Many public functions above simply write a command into the command // queue to batch the calls. validateDisplay and presentDisplay will call // this function to execute the command queue. Error execute(); sp<IComposer> mComposer; sp<IComposerClient> mClient; // 64KiB minus a small space for metadata such as read/write pointers static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16; CommandWriter mWriter; CommandReader mReader; // When true, the we attach to the vr_hwcomposer service instead of the // hwcomposer. This allows us to redirect surfaces to 3d surfaces in vr. const bool mIsUsingVrComposer; }; } // namespace Hwc2 } // namespace android #endif // ANDROID_SF_COMPOSER_HAL_H