1da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul/*
2da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * Copyright (C) 2015 The Android Open Source Project
3da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul *
4da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * Licensed under the Apache License, Version 2.0 (the "License");
5da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * you may not use this file except in compliance with the License.
6da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * You may obtain a copy of the License at
7da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul *
8da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul *      http://www.apache.org/licenses/LICENSE-2.0
9da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul *
10da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * Unless required by applicable law or agreed to in writing, software
11da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * distributed under the License is distributed on an "AS IS" BASIS,
12da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * See the License for the specific language governing permissions and
14da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul * limitations under the License.
15da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul */
16da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
175d8acfc2f9cd9a4f87ba6db4948a43783feeedc0Sean Paul#ifndef ANDROID_DRM_PLATFORM_H_
185d8acfc2f9cd9a4f87ba6db4948a43783feeedc0Sean Paul#define ANDROID_DRM_PLATFORM_H_
19da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
204c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul#include "drmdisplaycomposition.h"
217642c9230a7a5e30bd8e47d656d0d8f3162323f9Zach Reizner#include "drmhwcomposer.h"
22da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
23da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include <hardware/hardware.h>
24da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include <hardware/hwcomposer.h>
25da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
264c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul#include <map>
274c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul#include <vector>
284c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
29da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulnamespace android {
30da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
31da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulclass DrmResources;
32da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
33da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulclass Importer {
34da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul public:
35da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  virtual ~Importer() {
36da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  }
37da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
38da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  // Creates a platform-specific importer instance
39da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  static Importer *CreateInstance(DrmResources *drm);
40da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
41da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  // Imports the buffer referred to by handle into bo.
42da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  //
43da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  // Note: This can be called from a different thread than ReleaseBuffer. The
44da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  //       implementation is responsible for ensuring thread safety.
45da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  virtual int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) = 0;
46da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
47da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  // Releases the buffer object (ie: does the inverse of ImportBuffer)
48da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  //
49da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  // Note: This can be called from a different thread than ImportBuffer. The
50da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  //       implementation is responsible for ensuring thread safety.
51da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
52da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul};
534c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
544c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paulclass Planner {
554c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul public:
564c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  class PlanStage {
574c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul   public:
584c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    virtual ~PlanStage() {
594c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    }
604c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
614c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    virtual int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
624c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                                std::map<size_t, DrmHwcLayer *> &layers,
634c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                                DrmCrtc *crtc,
644c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                                std::vector<DrmPlane *> *planes) = 0;
654c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
664c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul   protected:
674c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    // Removes and returns the next available plane from planes
684c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
694c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      if (planes->empty())
704c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        return NULL;
714c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      DrmPlane *plane = planes->front();
724c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      planes->erase(planes->begin());
734c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      return plane;
744c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    }
754c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
764c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    // Finds and returns the squash layer from the composition
774c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    static DrmCompositionPlane *GetPrecomp(
784c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        std::vector<DrmCompositionPlane> *composition) {
794c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      auto l = GetPrecompIter(composition);
804c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      if (l == composition->end())
814c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        return NULL;
824c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      return &(*l);
834c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    }
844c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
854c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    // Inserts the given layer:plane in the composition right before the precomp
864c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    // layer
874c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    static int Emplace(std::vector<DrmCompositionPlane> *composition,
884c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                       std::vector<DrmPlane *> *planes,
894c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                       DrmCompositionPlane::Type type, DrmCrtc *crtc,
904c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                       size_t source_layer) {
914c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      DrmPlane *plane = PopPlane(planes);
924c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      if (!plane)
934c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        return -ENOENT;
944c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
954c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      auto precomp = GetPrecompIter(composition);
964c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      composition->emplace(precomp, type, plane, crtc, source_layer);
974c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      return 0;
984c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    }
994c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1004c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul   private:
1014c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    static std::vector<DrmCompositionPlane>::iterator GetPrecompIter(
1024c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        std::vector<DrmCompositionPlane> *composition) {
1034c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      return std::find_if(composition->begin(), composition->end(),
1044c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                          [](const DrmCompositionPlane &p) {
1054c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        return p.type() == DrmCompositionPlane::Type::kPrecomp;
1064c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      });
1074c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    }
1084c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  };
1094c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1104c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // Creates a planner instance with platform-specific planning stages
1114c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  static std::unique_ptr<Planner> CreateInstance(DrmResources *drm);
1124c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1134c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // Takes a stack of layers and provisions hardware planes for them. If the
1144c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // entire stack can't fit in hardware, the Planner may place the remaining
1154c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // layers in a PRECOMP plane. Layers in the PRECOMP plane will be composited
1164c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // using GL. PRECOMP planes should be placed above any 1:1 layer:plane
1174c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // compositions. If use_squash_fb is true, the Planner should try to reserve a
1184c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // plane at the highest z-order with type SQUASH.
1194c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  //
1204c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // @layers: a map of index:layer of layers to composite
1214c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // @use_squash_fb: reserve a squash framebuffer
1224c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // @primary_planes: a vector of primary planes available for this frame
1234c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // @overlay_planes: a vector of overlay planes available for this frame
1244c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  //
1254c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  // Returns: A tuple with the status of the operation (0 for success) and
1264c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  //          a vector of the resulting plan (ie: layer->plane mapping).
1274c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
1284c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      std::map<size_t, DrmHwcLayer *> &layers, bool use_squash_fb,
1294c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
1304c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      std::vector<DrmPlane *> *overlay_planes);
1314c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1324c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  template <typename T, typename... A>
1334c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  void AddStage(A &&... args) {
1344c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul    stages_.emplace_back(
1354c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul        std::unique_ptr<PlanStage>(new T(std::forward(args)...)));
1364c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  }
1374c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1384c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul private:
1394c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  std::vector<DrmPlane *> GetUsablePlanes(
1404c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
1414c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul      std::vector<DrmPlane *> *overlay_planes);
1424c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1434c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  std::vector<std::unique_ptr<PlanStage>> stages_;
1444c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul};
1454c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
1464c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul// This plan stage extracts all protected layers and places them on dedicated
1474c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul// planes.
1484c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paulclass PlanStageProtected : public Planner::PlanStage {
1494c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul public:
1504c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
1514c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
1524c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                      std::vector<DrmPlane *> *planes);
1534c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul};
1544c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul
15545002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido// This plan stage provisions the precomp plane with any remaining layers that
15645002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido// are on top of the current precomp layers. This stage should be included in
15745002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido// all platforms before loosely allocating layers (i.e. PlanStageGreedy) if
15845002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido// any previous plan could have modified the precomp plane layers
15945002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido// (ex. PlanStageProtected).
16045002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salidoclass PlanStagePrecomp : public Planner::PlanStage {
16145002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido public:
16245002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
16345002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido                      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
16445002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido                      std::vector<DrmPlane *> *planes);
16545002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido};
16645002321ef3a9023642cfb9854eb4171fa5653cbAdrian Salido
1674c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul// This plan stage places as many layers on dedicated planes as possible (first
1684c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul// come first serve), and then sticks the rest in a precomposition plane (if
1694c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul// needed).
1704c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paulclass PlanStageGreedy : public Planner::PlanStage {
1714c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul public:
1724c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul  int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
1734c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                      std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
1744c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul                      std::vector<DrmPlane *> *planes);
1754c4646e7b8a5cffdc8a2d53374b5340c07d14012Sean Paul};
176da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul}
177da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#endif
178