1/*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Zhaohan Ren  <zhaohan.ren@intel.com>
26 *    Jiang Fei  <jiang.fei@intel.com>
27 *    Binglin Chen <binglin.chen@intel.com>
28 *
29 */
30
31#include <binder/IPCThreadState.h>
32#include <binder/ProcessState.h>
33#include <binder/IServiceManager.h>
34#include <gui/Surface.h>
35#include <gui/SurfaceComposerClient.h>
36#include <gui/ISurfaceComposer.h>
37#include <binder/MemoryHeapBase.h>
38#include "psb_android_glue.h"
39#include "psb_output_android.h"
40#include <cutils/log.h>
41#include <ui/Rect.h>
42#include <system/window.h>
43#include <system/graphics.h>
44#ifdef TARGET_HAS_MULTIPLE_DISPLAY
45#include "psb_mds.h"
46#endif
47
48#ifdef  LOG_TAG
49#undef  LOG_TAG
50#endif
51
52#define LOG_TAG "pvr_drv_video"
53
54using namespace android;
55#ifdef TARGET_HAS_MULTIPLE_DISPLAY
56using namespace android::intel;
57#endif
58
59#ifdef TARGET_HAS_MULTIPLE_DISPLAY
60
61void init_mds_listener(void* output) {
62    psb_android_output_p aoutput = (psb_android_output_p)output;
63    if (aoutput == NULL) {
64        ALOGE("Invalid input parameter");
65        return;
66    }
67    if (aoutput->mds == NULL)
68        aoutput->mds = new psbMultiDisplayListener();
69}
70
71void deinit_mds_listener(void* output) {
72    psb_android_output_p aoutput = (psb_android_output_p)output;
73    if (aoutput == NULL) {
74        ALOGE("Invalid input parameter");
75        return;
76    }
77    if (aoutput->mds != NULL) {
78        delete (psbMultiDisplayListener*)(aoutput->mds);
79        aoutput->mds = NULL;
80    }
81}
82
83int psb_android_get_mds_mode(void* output) {
84    if (output == NULL)
85        return MDS_INIT_VALUE;
86    psb_android_output_p aoutput = (psb_android_output_p)output;
87    if (aoutput->mds == NULL)
88        init_mds_listener(aoutput);
89    psbMultiDisplayListener* mds =
90        static_cast<psbMultiDisplayListener*>(aoutput->mds);
91    if (mds == NULL)
92        return MDS_INIT_VALUE;
93    return mds->getMode();
94}
95
96int psb_android_get_mds_decoder_output_resolution(void* output,
97        int* width, int* height,
98        int* offX, int* offY,
99        int* bufW, int* bufH) {
100    if (output == NULL ||
101            width == NULL || height == NULL ||
102            offX  == NULL || offY == NULL ||
103            bufW  == NULL || bufH == NULL)
104        return 0;
105    psb_android_output_p aoutput = (psb_android_output_p)output;
106    if (aoutput->mds == NULL)
107        init_mds_listener(aoutput);
108    psbMultiDisplayListener* mds =
109        static_cast<psbMultiDisplayListener*>(aoutput->mds);
110    if (mds == NULL)
111        return 0;
112    bool ret = mds->getDecoderOutputResolution(width, height, offX, offY, bufW, bufH);
113    return (ret ? 1 : 0);
114}
115
116int psb_android_get_mds_vpp_state(void* output) {
117    bool ret = false;
118    if (output == NULL) {
119        sp<IServiceManager> sm = defaultServiceManager();
120        if (sm == NULL)
121            return 0;
122        sp<IMDService> imds = interface_cast<IMDService>(
123                sm->getService(String16(INTEL_MDS_SERVICE_NAME)));
124        if (imds == NULL)
125            return 0;
126        sp<IMultiDisplayInfoProvider> mds = imds->getInfoProvider();
127        if (mds != NULL) {
128            ret = mds->getVppState();
129        }
130        mds = NULL;
131        return (ret ? 1 : 0);
132    }
133    psb_android_output_p aoutput = (psb_android_output_p)output;
134    if (aoutput->mds == NULL)
135        init_mds_listener(aoutput);
136    psbMultiDisplayListener* mds =
137        static_cast<psbMultiDisplayListener*>(aoutput->mds);
138    ret = mds->getVppState();
139    if (mds == NULL)
140        return 0;
141    return (ret ? 1 : 0);
142}
143
144#else //TARGET_HAS_MULTIPLE_DISPLAY
145
146#ifdef PSBVIDEO_MRFL_VPP
147/* VPP is always enabled. It disables decoder rotate.
148 * TODO: remove the dependency the on libVPP. Get it form ISB configure
149 */
150int psb_android_get_vpp_state() {
151    return 1;
152}
153
154#endif
155#endif
156
157unsigned int update_forced;
158
159int psb_android_surfaceflinger_rotate(void* native_window, int *rotation)
160{
161    sp<ANativeWindow> mNativeWindow = static_cast<ANativeWindow*>(native_window);
162    int err, transform_hint;
163
164    if (mNativeWindow.get()) {
165        err = mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_TRANSFORM_HINT, &transform_hint);
166        if (err != 0) {
167            ALOGE("%s: NATIVE_WINDOW_TRANSFORM_HINT query failed", __func__);
168            return -1;
169        }
170        switch (transform_hint) {
171        case HAL_TRANSFORM_ROT_90:
172            *rotation = 1;
173            break;
174        case HAL_TRANSFORM_ROT_180:
175            *rotation = 2;
176            break;
177        case HAL_TRANSFORM_ROT_270:
178            *rotation = 3;
179            break;
180        default:
181            *rotation = 0;
182        }
183    }
184    return 0;
185}
186