OSDN Git Service

Fix dEQP-EGL.functional.resize.pixel_density.*
authorLingfeng Yang <lfy@google.com>
Fri, 23 Sep 2016 20:49:09 +0000 (13:49 -0700)
committerLingfeng Yang <lfy@google.com>
Fri, 23 Sep 2016 21:37:48 +0000 (14:37 -0700)
bug: 31703045

These tests attempt to calculate native DPI by creating
very small buffers, rendering them to a high resolution screen,
and then re-deriving the native DPI by scaling buffer size
against the window resolution in screen pixels.

Previously, they failed because EGL_HORIZONTAL_RESOLUTION
actually means to get the effective DPI of an EGL texture,
which is different from native DPI.

For example, if the screen is 2 pixels across and 4 meters wide,
the native dot pitch is 0.5 pixels per meter, but if
there is a 1x1 pixel texture filling the entire screen,
EGL_HORIZONTAL_RESOLUTION should return 0.25 pixels
per meter (1 texture pixel, 4 meters -> 0.25 ppm).

This CL queries the native window resolution and attempts
to calculate effective DPI from that.

Change-Id: I7f12d7964529bc95b5f89640dea00e9e16c66799

system/egl/egl.cpp

index 849e238..9132e0e 100644 (file)
@@ -227,6 +227,8 @@ struct egl_surface_t {
 
     EGLint      getWidth(){ return width; }
     EGLint      getHeight(){ return height; }
+    EGLint      getNativeWidth(){ return nativeWidth; }
+    EGLint      getNativeHeight(){ return nativeHeight; }
     void        setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; }
     EGLint      getTextureFormat() { return texFormat; }
     void        setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; }
@@ -241,9 +243,16 @@ private:
     EGLint      texFormat;
     EGLint      texTarget;
 
+    // Width of the actual window being presented (not the EGL texture)
+    // Give it some default values.
+    int nativeWidth;
+    int nativeHeight;
+
 protected:
     void        setWidth(EGLint w)  { width = w;  }
     void        setHeight(EGLint h) { height = h; }
+    void        setNativeWidth(int w)  { nativeWidth = w;  }
+    void        setNativeHeight(int h) { nativeHeight = h; }
 
     EGLint      surfaceType;
     uint32_t    rcSurface; //handle to surface created via remote control
@@ -254,6 +263,9 @@ egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceTyp
 {
     width = 0;
     height = 0;
+    // prevent div by 0 in EGL_(HORIZONTAL|VERTICAL)_RESOLUTION queries.
+    nativeWidth = 1;
+    nativeHeight = 1;
     texFormat = EGL_NO_TEXTURE;
     texTarget = EGL_NO_TEXTURE;
     assert(dpy == (EGLDisplay)&s_display);
@@ -313,6 +325,13 @@ EGLBoolean egl_window_surface_t::init()
     setWidth(buffer->width);
     setHeight(buffer->height);
 
+    int nativeWidth, nativeHeight;
+          nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &nativeWidth);
+          nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &nativeHeight);
+
+    setNativeWidth(nativeWidth);
+    setNativeHeight(nativeHeight);
+
     DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
     rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config,
             getWidth(), getHeight());
@@ -904,6 +923,11 @@ EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribu
     VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
 
     egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+
+    // Parameters involved in queries of EGL_(HORIZONTAL|VERTICAL)_RESOLUTION
+    // TODO: get the DPI from avd config
+    float fakeNativeDPI = 420.0;
+    float currWidth, currHeight, scaledResolution, effectiveSurfaceDPI;
     EGLBoolean ret = EGL_TRUE;
     switch (attribute) {
         case EGL_CONFIG_ID:
@@ -960,13 +984,21 @@ EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribu
             break;
         case EGL_HORIZONTAL_RESOLUTION:
             // pixel/mm * EGL_DISPLAY_SCALING
-            // TODO: get the real resolution from avd config
-            *value = 1 * EGL_DISPLAY_SCALING;
+            // TODO: get the DPI from avd config
+            currWidth = surface->getWidth();
+            scaledResolution = currWidth / surface->getNativeWidth();
+            effectiveSurfaceDPI =
+                scaledResolution * fakeNativeDPI * EGL_DISPLAY_SCALING;
+            *value = (EGLint)(effectiveSurfaceDPI);
             break;
         case EGL_VERTICAL_RESOLUTION:
             // pixel/mm * EGL_DISPLAY_SCALING
-            // TODO: get the real resolution from avd config
-            *value = 1 * EGL_DISPLAY_SCALING;
+            // TODO: get the real DPI from avd config
+            currHeight = surface->getHeight();
+            scaledResolution = currHeight / surface->getNativeHeight();
+            effectiveSurfaceDPI =
+                scaledResolution * fakeNativeDPI * EGL_DISPLAY_SCALING;
+            *value = (EGLint)(effectiveSurfaceDPI);
             break;
         case EGL_PIXEL_ASPECT_RATIO:
             // w / h * EGL_DISPLAY_SCALING