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 
54 using namespace android;
55 #ifdef TARGET_HAS_MULTIPLE_DISPLAY
56 using namespace android::intel;
57 #endif
58 
59 #ifdef TARGET_HAS_MULTIPLE_DISPLAY
60 
init_mds_listener(void * output)61 void 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 
deinit_mds_listener(void * output)71 void 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 
psb_android_get_mds_mode(void * output)83 int 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 
psb_android_get_mds_decoder_output_resolution(void * output,int * width,int * height,int * offX,int * offY,int * bufW,int * bufH)96 int 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 
psb_android_get_mds_vpp_state(void * output)116 int 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  */
psb_android_get_vpp_state()150 int psb_android_get_vpp_state() {
151     return 1;
152 }
153 
154 #endif
155 #endif
156 
157 unsigned int update_forced;
158 
psb_android_surfaceflinger_rotate(void * native_window,int * rotation)159 int 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