diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 2e0eb76ccb..d6fbd1640d 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -362,7 +362,8 @@ bool Framework::AttachSurface(JNIEnv * env, jobject jSurface) if (m_isSurfaceDestroyed) { LOG(LINFO, ("Recover surface, viewport size:", w, h)); - m_work.OnRecoverSurface(w, h); + bool const recreateContextDependentResources = (m_vulkanContextFactory == nullptr); + m_work.OnRecoverSurface(w, h, recreateContextDependentResources); m_isSurfaceDestroyed = false; m_work.EnterForeground(); diff --git a/data/vulkan_shaders/reflection.json b/data/vulkan_shaders/reflection.json index 60d29bbf84..ce7e49047f 100644 --- a/data/vulkan_shaders/reflection.json +++ b/data/vulkan_shaders/reflection.json @@ -1 +1 @@ -[{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":38,"fs_off":4268,"fs_size":2552,"vs_off":0,"vs_size":4268},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":5,"fs_off":11140,"fs_size":2072,"vs_off":6820,"vs_size":4320},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":10,"fs_off":16444,"fs_size":1336,"vs_off":13212,"vs_size":3232},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":3,"fs_off":21876,"fs_size":2456,"vs_off":17780,"vs_size":4096},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":12,"fs_off":27824,"fs_size":1892,"vs_off":24332,"vs_size":3492},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":13,"fs_off":32016,"fs_size":1336,"vs_off":29716,"vs_size":2300},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":2,"fs_off":36804,"fs_size":1732,"vs_off":33352,"vs_size":3452},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":15,"fs_off":42112,"fs_size":2092,"vs_off":38536,"vs_size":3576},{"info":{"vs_uni":-1,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":34,"fs_off":45124,"fs_size":1168,"vs_off":44204,"vs_size":920},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":49,"fs_off":49676,"fs_size":1604,"vs_off":46292,"vs_size":3384},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":27,"fs_off":57028,"fs_size":3464,"vs_off":51280,"vs_size":5748},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":39,"fs_off":64548,"fs_size":1496,"vs_off":60492,"vs_size":4056},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":29,"fs_off":70620,"fs_size":3228,"vs_off":66044,"vs_size":4576},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":18,"fs_off":77728,"fs_size":1496,"vs_off":73848,"vs_size":3880},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_blendingWeightTex","idx":2}]},"prg":53,"fs_off":80596,"fs_size":3584,"vs_off":79224,"vs_size":1372},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":36,"fs_off":85828,"fs_size":1488,"vs_off":84180,"vs_size":1648},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":21,"fs_off":89380,"fs_size":1404,"vs_off":87316,"vs_size":2064},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":4,"fs_off":94880,"fs_size":2456,"vs_off":90784,"vs_size":4096},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":23,"fs_off":101320,"fs_size":1496,"vs_off":97336,"vs_size":3984},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":7,"fs_off":106464,"fs_size":1748,"vs_off":102816,"vs_size":3648},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_smaaArea","idx":2},{"frag":1,"name":"u_smaaSearch","idx":3}]},"prg":52,"fs_off":110512,"fs_size":12056,"vs_off":108212,"vs_size":2300},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":48,"fs_off":128860,"fs_size":3472,"vs_off":122568,"vs_size":6292},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":30,"fs_off":135848,"fs_size":2344,"vs_off":132332,"vs_size":3516},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":45,"fs_off":143108,"fs_size":2072,"vs_off":138192,"vs_size":4916},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":16,"fs_off":150540,"fs_size":1800,"vs_off":145180,"vs_size":5360},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":43,"fs_off":156980,"fs_size":2456,"vs_off":152340,"vs_size":4640},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":14,"fs_off":164680,"fs_size":1944,"vs_off":159436,"vs_size":5244},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":22,"fs_off":170320,"fs_size":1496,"vs_off":166624,"vs_size":3696},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":40,"fs_off":176020,"fs_size":1732,"vs_off":171816,"vs_size":4204},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":31,"fs_off":181848,"fs_size":2456,"vs_off":177752,"vs_size":4096},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":47,"fs_off":188704,"fs_size":1748,"vs_off":184304,"vs_size":4400},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":41,"fs_off":195092,"fs_size":2456,"vs_off":190452,"vs_size":4640},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":50,"fs_off":203456,"fs_size":2416,"vs_off":197548,"vs_size":5908},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":46,"fs_off":210272,"fs_size":2072,"vs_off":205872,"vs_size":4400},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":44,"fs_off":216984,"fs_size":2456,"vs_off":212344,"vs_size":4640},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":42,"fs_off":224080,"fs_size":2456,"vs_off":219440,"vs_size":4640},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":26,"fs_off":232284,"fs_size":3512,"vs_off":226536,"vs_size":5748},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":0,"fs_off":239448,"fs_size":2552,"vs_off":235796,"vs_size":3652},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":1,"fs_off":245304,"fs_size":1496,"vs_off":242000,"vs_size":3304},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":37,"fs_off":248448,"fs_size":1552,"vs_off":246800,"vs_size":1648},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":9,"fs_off":253092,"fs_size":1980,"vs_off":250000,"vs_size":3092},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":20,"fs_off":256892,"fs_size":1404,"vs_off":255072,"vs_size":1820},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":25,"fs_off":262644,"fs_size":1984,"vs_off":258296,"vs_size":4348},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":28,"fs_off":269676,"fs_size":2216,"vs_off":264628,"vs_size":5048},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":11,"fs_off":275124,"fs_size":1336,"vs_off":271892,"vs_size":3232},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":6,"fs_off":280108,"fs_size":2072,"vs_off":276460,"vs_size":3648},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":24,"fs_off":287064,"fs_size":832,"vs_off":282180,"vs_size":4884},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":19,"fs_off":291292,"fs_size":1704,"vs_off":287896,"vs_size":3396},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":35,"fs_off":294940,"fs_size":1824,"vs_off":292996,"vs_size":1944},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":51,"fs_off":298688,"fs_size":4000,"vs_off":296764,"vs_size":1924},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":8,"fs_off":305780,"fs_size":1980,"vs_off":302688,"vs_size":3092},{"info":{"vs_uni":-1,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":33,"fs_off":308864,"fs_size":992,"vs_off":307760,"vs_size":1104},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":32,"fs_off":313952,"fs_size":2456,"vs_off":309856,"vs_size":4096},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":17,"fs_off":322032,"fs_size":2372,"vs_off":316408,"vs_size":5624}] \ No newline at end of file +[{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":38,"fs_off":4268,"fs_size":2552,"vs_off":0,"vs_size":4268},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":5,"fs_off":11140,"fs_size":2072,"vs_off":6820,"vs_size":4320},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":10,"fs_off":16444,"fs_size":1336,"vs_off":13212,"vs_size":3232},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":3,"fs_off":21876,"fs_size":2456,"vs_off":17780,"vs_size":4096},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":12,"fs_off":27824,"fs_size":1892,"vs_off":24332,"vs_size":3492},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":13,"fs_off":32312,"fs_size":1336,"vs_off":29716,"vs_size":2596},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":2,"fs_off":37100,"fs_size":1732,"vs_off":33648,"vs_size":3452},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":15,"fs_off":42408,"fs_size":2092,"vs_off":38832,"vs_size":3576},{"info":{"vs_uni":-1,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":34,"fs_off":45420,"fs_size":1168,"vs_off":44500,"vs_size":920},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":49,"fs_off":49972,"fs_size":1604,"vs_off":46588,"vs_size":3384},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":27,"fs_off":57324,"fs_size":3464,"vs_off":51576,"vs_size":5748},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":39,"fs_off":64844,"fs_size":1496,"vs_off":60788,"vs_size":4056},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":29,"fs_off":70916,"fs_size":3228,"vs_off":66340,"vs_size":4576},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":18,"fs_off":78024,"fs_size":1496,"vs_off":74144,"vs_size":3880},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_blendingWeightTex","idx":2}]},"prg":53,"fs_off":80892,"fs_size":3584,"vs_off":79520,"vs_size":1372},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":36,"fs_off":86124,"fs_size":1488,"vs_off":84476,"vs_size":1648},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":21,"fs_off":89676,"fs_size":1404,"vs_off":87612,"vs_size":2064},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":4,"fs_off":95176,"fs_size":2456,"vs_off":91080,"vs_size":4096},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":23,"fs_off":101616,"fs_size":1496,"vs_off":97632,"vs_size":3984},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":7,"fs_off":106760,"fs_size":1748,"vs_off":103112,"vs_size":3648},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_smaaArea","idx":2},{"frag":1,"name":"u_smaaSearch","idx":3}]},"prg":52,"fs_off":110808,"fs_size":12056,"vs_off":108508,"vs_size":2300},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":48,"fs_off":129156,"fs_size":3472,"vs_off":122864,"vs_size":6292},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":30,"fs_off":136144,"fs_size":2344,"vs_off":132628,"vs_size":3516},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":45,"fs_off":143404,"fs_size":2072,"vs_off":138488,"vs_size":4916},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":16,"fs_off":150836,"fs_size":1800,"vs_off":145476,"vs_size":5360},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":43,"fs_off":157276,"fs_size":2456,"vs_off":152636,"vs_size":4640},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":14,"fs_off":164976,"fs_size":1944,"vs_off":159732,"vs_size":5244},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":22,"fs_off":170616,"fs_size":1496,"vs_off":166920,"vs_size":3696},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":40,"fs_off":176316,"fs_size":1732,"vs_off":172112,"vs_size":4204},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":31,"fs_off":182144,"fs_size":2456,"vs_off":178048,"vs_size":4096},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":47,"fs_off":189000,"fs_size":1748,"vs_off":184600,"vs_size":4400},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":41,"fs_off":195388,"fs_size":2456,"vs_off":190748,"vs_size":4640},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":50,"fs_off":203752,"fs_size":2416,"vs_off":197844,"vs_size":5908},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":46,"fs_off":210568,"fs_size":2072,"vs_off":206168,"vs_size":4400},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":44,"fs_off":217280,"fs_size":2456,"vs_off":212640,"vs_size":4640},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":42,"fs_off":224376,"fs_size":2456,"vs_off":219736,"vs_size":4640},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":26,"fs_off":232580,"fs_size":3512,"vs_off":226832,"vs_size":5748},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":0,"fs_off":239744,"fs_size":2552,"vs_off":236092,"vs_size":3652},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":1,"fs_off":245600,"fs_size":1496,"vs_off":242296,"vs_size":3304},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":37,"fs_off":248744,"fs_size":1552,"vs_off":247096,"vs_size":1648},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":9,"fs_off":253388,"fs_size":1980,"vs_off":250296,"vs_size":3092},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":20,"fs_off":257188,"fs_size":1404,"vs_off":255368,"vs_size":1820},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":25,"fs_off":262940,"fs_size":1984,"vs_off":258592,"vs_size":4348},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":28,"fs_off":269972,"fs_size":2216,"vs_off":264924,"vs_size":5048},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1}],"fs_uni":0},"prg":11,"fs_off":275420,"fs_size":1336,"vs_off":272188,"vs_size":3232},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":6,"fs_off":280404,"fs_size":2072,"vs_off":276756,"vs_size":3648},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":24,"fs_off":287360,"fs_size":832,"vs_off":282476,"vs_size":4884},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":19,"fs_off":291588,"fs_size":1704,"vs_off":288192,"vs_size":3396},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":35,"fs_off":295236,"fs_size":1824,"vs_off":293292,"vs_size":1944},{"info":{"vs_uni":0,"fs_uni":-1,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":51,"fs_off":298984,"fs_size":4000,"vs_off":297060,"vs_size":1924},{"info":{"vs_uni":0,"tex":[{"frag":0,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}],"fs_uni":0},"prg":8,"fs_off":306076,"fs_size":1980,"vs_off":302984,"vs_size":3092},{"info":{"vs_uni":-1,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":33,"fs_off":309160,"fs_size":992,"vs_off":308056,"vs_size":1104},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1}]},"prg":32,"fs_off":314248,"fs_size":2456,"vs_off":310152,"vs_size":4096},{"info":{"vs_uni":0,"fs_uni":0,"tex":[{"frag":1,"name":"u_colorTex","idx":1},{"frag":1,"name":"u_maskTex","idx":2}]},"prg":17,"fs_off":322328,"fs_size":2372,"vs_off":316704,"vs_size":5624}] \ No newline at end of file diff --git a/data/vulkan_shaders/shaders_pack.spv b/data/vulkan_shaders/shaders_pack.spv index e53de46e20..f1a5fd2b08 100644 Binary files a/data/vulkan_shaders/shaders_pack.spv and b/data/vulkan_shaders/shaders_pack.spv differ diff --git a/drape/drape_routine.hpp b/drape/drape_routine.hpp index 210ce26df3..856ca88c5f 100644 --- a/drape/drape_routine.hpp +++ b/drape/drape_routine.hpp @@ -19,8 +19,6 @@ namespace dp // OpenGL data), use FR/BR threads for that. class DrapeRoutine { - friend class Promise; - public: class Result { @@ -64,7 +62,7 @@ public: static ResultPtr Run(Task && t) { ResultPtr result(new Result(Instance().GetNextId())); - bool const success = Instance().m_workerThread.Push([result, t]() mutable + bool const success = Instance().m_workerThread.Push([result, t = std::move(t)]() mutable { t(); Instance().Notify(result->Finish()); @@ -80,7 +78,24 @@ public: static ResultPtr RunDelayed(base::thread_pool::delayed::ThreadPool::Duration const & duration, Task && t) { ResultPtr result(new Result(Instance().GetNextId())); - bool const success = Instance().m_workerThread.PushDelayed(duration, [result, t]() mutable + bool const success = Instance().m_workerThread.PushDelayed(duration, [result, t = std::move(t)]() mutable + { + t(); + Instance().Notify(result->Finish()); + }); + + if (!success) + return {}; + + return result; + } + + // Asynchronous execution for tasks when execution order matters. + template + static ResultPtr RunSequential(Task && t) + { + ResultPtr result(new Result(Instance().GetNextId())); + bool const success = Instance().m_sequentialWorkerThread.Push([result, t = std::move(t)]() mutable { t(); Instance().Notify(result->Finish()); @@ -129,6 +144,7 @@ private: void FinishAll() { m_workerThread.ShutdownAndJoin(); + m_sequentialWorkerThread.ShutdownAndJoin(); std::lock_guard lock(m_mutex); m_finished = true; @@ -141,6 +157,7 @@ private: std::condition_variable m_condition; std::mutex m_mutex; base::thread_pool::delayed::ThreadPool m_workerThread; + base::thread_pool::delayed::ThreadPool m_sequentialWorkerThread; }; // This is a helper class, which aggregates logic of waiting for active @@ -179,10 +196,9 @@ public: void Remove(std::shared_ptr const & task) { std::lock_guard lock(m_mutex); - m_tasks.erase( - std::remove_if(m_tasks.begin(), m_tasks.end(), - [task](ActiveTask const & t) { return t.m_task == task; }), - m_tasks.end()); + m_tasks.erase(std::remove_if(m_tasks.begin(), m_tasks.end(), + [task](ActiveTask const & t) { return t.m_task == task; }), + m_tasks.end()); } void FinishAll() diff --git a/drape/metal/metal_vertex_array_buffer_impl.mm b/drape/metal/metal_vertex_array_buffer_impl.mm index 313251e2be..09abaa1876 100644 --- a/drape/metal/metal_vertex_array_buffer_impl.mm +++ b/drape/metal/metal_vertex_array_buffer_impl.mm @@ -36,6 +36,8 @@ public: void RenderRange(ref_ptr context, bool drawAsLine, IndicesRange const & range) override { + CHECK(m_vertexArrayBuffer->HasBuffers(), ()); + ref_ptr metalContext = context; if (!metalContext->HasAppliedPipelineState()) return; diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp index 5409e5646c..68da68d5aa 100644 --- a/drape/vertex_array_buffer.cpp +++ b/drape/vertex_array_buffer.cpp @@ -180,7 +180,7 @@ void VertexArrayBuffer::Render(ref_ptr context, bool drawAsLine void VertexArrayBuffer::RenderRange(ref_ptr context, bool drawAsLine, IndicesRange const & range) { - if (!(m_staticBuffers.empty() && m_dynamicBuffers.empty()) && GetIndexCount() > 0) + if (HasBuffers() && GetIndexCount() > 0) { // If OES_vertex_array_object is supported than all bindings have already saved in VAO // and we need only bind VAO. @@ -202,6 +202,9 @@ void VertexArrayBuffer::Build(ref_ptr context, ref_ptrGetApiVersion(); @@ -226,9 +229,7 @@ void VertexArrayBuffer::Build(ref_ptr context, ref_ptrBuild(program)) return; @@ -408,13 +409,17 @@ void VertexArrayBuffer::ApplyMutation(ref_ptr context, bool VertexArrayBuffer::Bind() const { - CHECK(m_impl != nullptr, ()); + if (m_impl == nullptr) + return false; + return m_impl->Bind(); } void VertexArrayBuffer::Unbind() const { - CHECK(m_impl != nullptr, ()); + if (m_impl == nullptr) + return; + m_impl->Unbind(); } diff --git a/drape/vertex_array_buffer.hpp b/drape/vertex_array_buffer.hpp index de2b111ad7..34a7277049 100644 --- a/drape/vertex_array_buffer.hpp +++ b/drape/vertex_array_buffer.hpp @@ -84,6 +84,7 @@ public: void ResetChangingTracking() { m_isChanged = false; } bool IsChanged() const { return m_isChanged; } + bool HasBuffers() const { return !m_staticBuffers.empty() || !m_dynamicBuffers.empty(); } private: ref_ptr GetOrCreateStaticBuffer(BindingInfo const & bindingInfo); diff --git a/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp b/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp index 6bf5d451e4..324ff29f99 100644 --- a/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp +++ b/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp @@ -53,6 +53,8 @@ public: void RenderRange(ref_ptr context, bool drawAsLine, IndicesRange const & range) override { + CHECK(m_vertexArrayBuffer->HasBuffers(), ()); + ref_ptr vulkanContext = context; VkCommandBuffer commandBuffer = vulkanContext->GetCurrentRenderingCommandBuffer(); CHECK(commandBuffer != nullptr, ()); diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 7de05e166d..12f6abe1a4 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -134,7 +134,7 @@ DrapeEngine::~DrapeEngine() m_glyphGenerator.reset(); } -void DrapeEngine::Update(int w, int h) +void DrapeEngine::RecoverSurface(int w, int h, bool recreateContextDependentResources) { if (m_choosePositionMode) { @@ -142,13 +142,15 @@ void DrapeEngine::Update(int w, int h) make_unique_dp(), MessagePriority::Normal); } - RecacheGui(false); - RecacheMapShapes(); - - m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(), - MessagePriority::Normal); + if (recreateContextDependentResources) + { + RecacheGui(false); + RecacheMapShapes(); + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(), + MessagePriority::Normal); + } ResizeImpl(w, h); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 93fadf27e7..2c4f21fd43 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -117,7 +117,7 @@ public: DrapeEngine(Params && params); ~DrapeEngine(); - void Update(int w, int h); + void RecoverSurface(int w, int h, bool recreateContextDependentResources); void Resize(int w, int h); void Invalidate(); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 8cabcd64e3..8e8bd28c3c 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -474,8 +474,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) { m_routeRenderer->UpdateDistanceFromBegin(info.GetDistanceFromBegin()); // Here we have to recache route arrows. - m_routeRenderer->UpdateRoute(m_userEventStream.GetCurrentScreen(), - std::bind(&FrontendRenderer::OnCacheRouteArrows, this, _1, _2)); + m_routeRenderer->PrepareRouteArrows(m_userEventStream.GetCurrentScreen(), + std::bind(&FrontendRenderer::OnPrepareRouteArrows, this, _1, _2)); } break; @@ -514,8 +514,8 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) m_routeRenderer->AddSubrouteData(m_context, std::move(subrouteData), make_ref(m_gpuProgramManager)); // Here we have to recache route arrows. - m_routeRenderer->UpdateRoute(m_userEventStream.GetCurrentScreen(), - std::bind(&FrontendRenderer::OnCacheRouteArrows, this, _1, _2)); + m_routeRenderer->PrepareRouteArrows(m_userEventStream.GetCurrentScreen(), + std::bind(&FrontendRenderer::OnPrepareRouteArrows, this, _1, _2)); if (m_pendingFollowRoute != nullptr) { @@ -642,9 +642,18 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } - case Message::Type::RecoverGLResources: + case Message::Type::PrepareSubrouteArrows: { - UpdateGLResources(); + ref_ptr msg = message; + m_routeRenderer->CacheRouteArrows(m_userEventStream.GetCurrentScreen(), + msg->GetSubrouteId(), msg->AcceptBorders(), + std::bind(&FrontendRenderer::OnCacheRouteArrows, this, _1, _2)); + break; + } + + case Message::Type::RecoverContextDependentResources: + { + UpdateContextDependentResources(); break; } @@ -683,7 +692,7 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) blocker.Wait(); } - UpdateGLResources(); + UpdateContextDependentResources(); break; } @@ -996,7 +1005,7 @@ unique_ptr FrontendRenderer::CreateRoutine() return make_unique(*this); } -void FrontendRenderer::UpdateGLResources() +void FrontendRenderer::UpdateContextDependentResources() { ++m_lastRecacheRouteId; @@ -1011,7 +1020,7 @@ void FrontendRenderer::UpdateGLResources() m_trafficRenderer->ClearContextDependentResources(); - // In some cases UpdateGLResources can be called before the rendering of + // In some cases UpdateContextDependentResources can be called before the rendering of // the first frame. m_currentZoomLevel will be equal to -1, so ResolveTileKeys // could not be called. if (m_currentZoomLevel > 0) @@ -2406,7 +2415,7 @@ void FrontendRenderer::PrepareScene(ScreenBase const & modelView) RefreshPivotTransform(modelView); m_myPositionController->OnUpdateScreen(modelView); - m_routeRenderer->UpdateRoute(modelView, std::bind(&FrontendRenderer::OnCacheRouteArrows, this, _1, _2)); + m_routeRenderer->PrepareRouteArrows(modelView, std::bind(&FrontendRenderer::OnPrepareRouteArrows, this, _1, _2)); } void FrontendRenderer::UpdateScene(ScreenBase const & modelView) @@ -2448,10 +2457,17 @@ void FrontendRenderer::EmitModelViewChanged(ScreenBase const & modelView) const m_modelViewChangedFn(modelView); } -void FrontendRenderer::OnCacheRouteArrows(int routeIndex, std::vector const & borders) +void FrontendRenderer::OnPrepareRouteArrows(dp::DrapeID subrouteIndex, std::vector && borders) +{ + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(subrouteIndex, std::move(borders)), + MessagePriority::Normal); +} + +void FrontendRenderer::OnCacheRouteArrows(dp::DrapeID subrouteIndex, std::vector const & borders) { m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(routeIndex, borders, m_lastRecacheRouteId), + make_unique_dp(subrouteIndex, borders, m_lastRecacheRouteId), MessagePriority::Normal); } diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 447d365ab3..14227e6651 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -226,7 +226,7 @@ private: }; void ReleaseResources(); - void UpdateGLResources(); + void UpdateContextDependentResources(); void BeginUpdateOverlayTree(ScreenBase const & modelView); void UpdateOverlayTree(ScreenBase const & modelView, drape_ptr & renderGroup); @@ -255,7 +255,8 @@ private: void ProcessSelection(ref_ptr msg); - void OnCacheRouteArrows(int routeIndex, std::vector const & borders); + void OnPrepareRouteArrows(dp::DrapeID subrouteIndex, std::vector && borders); + void OnCacheRouteArrows(dp::DrapeID subrouteIndex, std::vector const & borders); void CollectShowOverlaysEvents(); diff --git a/drape_frontend/message.cpp b/drape_frontend/message.cpp index 89925e12a2..f2f170174b 100644 --- a/drape_frontend/message.cpp +++ b/drape_frontend/message.cpp @@ -37,6 +37,7 @@ std::string DebugPrint(Message::Type msgType) case Message::Type::SelectObject: return "SelectObject"; case Message::Type::AddSubroute: return "AddSubroute"; case Message::Type::RemoveSubroute: return "RemoveSubroute"; + case Message::Type::PrepareSubrouteArrows: return "PrepareSubrouteArrows"; case Message::Type::CacheSubrouteArrows: return "CacheSubrouteArrows"; case Message::Type::FlushSubroute: return "FlushSubroute"; case Message::Type::FlushSubrouteArrows: return "FlushSubrouteArrows"; @@ -64,7 +65,7 @@ std::string DebugPrint(Message::Type msgType) case Message::Type::SetDisplacementMode: return "SetDisplacementMode"; case Message::Type::AllowAutoZoom: return "AllowAutoZoom"; case Message::Type::RequestSymbolsSize: return "RequestSymbolsSize"; - case Message::Type::RecoverGLResources: return "RecoverGLResources"; + case Message::Type::RecoverContextDependentResources: return "RecoverContextDependentResources"; case Message::Type::SetVisibleViewport: return "SetVisibleViewport"; case Message::Type::EnableTraffic: return "EnableTraffic"; case Message::Type::FlushTrafficGeometry: return "FlushTrafficGeometry"; diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 9a1d1db343..49f4e6c84a 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -38,6 +38,7 @@ public: SelectObject, AddSubroute, RemoveSubroute, + PrepareSubrouteArrows, CacheSubrouteArrows, FlushSubroute, FlushSubrouteArrows, @@ -65,7 +66,7 @@ public: SetDisplacementMode, AllowAutoZoom, RequestSymbolsSize, - RecoverGLResources, + RecoverContextDependentResources, SetVisibleViewport, EnableTraffic, FlushTrafficGeometry, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 6db408c2a7..874733974f 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -561,6 +561,24 @@ private: int const m_recacheId; }; +class PrepareSubrouteArrowsMessage : public Message +{ +public: + PrepareSubrouteArrowsMessage(dp::DrapeID subrouteId, + std::vector && borders) + : m_subrouteId(subrouteId) + , m_borders(std::move(borders)) + {} + + Type GetType() const override { return Type::PrepareSubrouteArrows; } + dp::DrapeID GetSubrouteId() const { return m_subrouteId; } + std::vector && AcceptBorders() { return std::move(m_borders); } + +private: + dp::DrapeID m_subrouteId; + std::vector m_borders; +}; + class CacheSubrouteArrowsMessage : public Message { public: @@ -711,10 +729,10 @@ public: Type GetType() const override { return Type::Invalidate; } }; -class RecoverGLResourcesMessage : public Message +class RecoverContextDependentResourcesMessage : public Message { public: - Type GetType() const override { return Type::RecoverGLResources; } + Type GetType() const override { return Type::RecoverContextDependentResources; } bool IsGraphicsContextDependent() const override { return true; } }; diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 5326ae11a7..5ce4ee29c8 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -5,6 +5,7 @@ #include "shaders/programs.hpp" +#include "drape/drape_routine.hpp" #include "drape/glsl_func.hpp" #include "drape/utils/projection.hpp" #include "drape/vertex_array_buffer.hpp" @@ -145,17 +146,17 @@ bool AreEqualArrowBorders(std::vector const & borders1, return true; } -std::vector CalculateArrowBorders(ScreenBase const & screen, float currentHalfWidth, - RouteRenderer::SubrouteInfo const & subrouteInfo, - double distanceFromBegin) +std::vector CalculateArrowBorders(m2::RectD screenRect, double screenScale, + float currentHalfWidth, SubrouteConstPtr const & subroute, + double subrouteLength, double distanceFromBegin) { - auto const & turns = subrouteInfo.m_subroute->m_turns; + auto const & turns = subroute->m_turns; if (turns.empty()) return {}; // Calculate arrow mercator length. double glbHalfLen = 0.5 * kArrowSize; - double const glbHalfTextureWidth = currentHalfWidth * kArrowHeightFactor * screen.GetScale(); + double const glbHalfTextureWidth = currentHalfWidth * kArrowHeightFactor * screenScale; double const glbHalfTextureLen = glbHalfTextureWidth * kArrowAspect; if (glbHalfLen < glbHalfTextureLen) glbHalfLen = glbHalfTextureLen; @@ -164,20 +165,20 @@ std::vector CalculateArrowBorders(ScreenBase const & screen, float double const glbArrowTail = 2.0 * kArrowTailSize * glbHalfTextureLen; double const glbMinArrowSize = glbArrowHead + glbArrowTail; - double const kExtendCoef = 1.1; - m2::RectD screenRect = screen.ClipRect(); - screenRect.Scale(kExtendCoef); + double constexpr kExtentCoef = 1.1; + screenRect.Scale(kExtentCoef); // Calculate arrow borders. + size_t constexpr kAverageArrowsCount = 10; std::vector newArrowBorders; - newArrowBorders.reserve(turns.size()); - auto const & polyline = subrouteInfo.m_subroute->m_polyline; + newArrowBorders.reserve(kAverageArrowsCount); + auto const & polyline = subroute->m_polyline; for (size_t i = 0; i < turns.size(); i++) { ArrowBorders arrowBorders; arrowBorders.m_groupIndex = static_cast(i); arrowBorders.m_startDistance = std::max(0.0, turns[i] - glbHalfLen * 0.8); - arrowBorders.m_endDistance = std::min(subrouteInfo.m_length, turns[i] + glbHalfLen * 1.2); + arrowBorders.m_endDistance = std::min(subrouteLength, turns[i] + glbHalfLen * 1.2); if ((arrowBorders.m_endDistance - arrowBorders.m_startDistance) < glbMinArrowSize || arrowBorders.m_startDistance < distanceFromBegin) @@ -248,9 +249,9 @@ RouteRenderer::RouteRenderer(PreviewPointsRequestCallback && previewPointsReques ASSERT(m_previewPointsRequest != nullptr, ()); } -void RouteRenderer::UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallback const & callback) +void RouteRenderer::PrepareRouteArrows(ScreenBase const & screen, + PrepareRouteArrowsCallback const & prepareCallback) { - ASSERT(callback != nullptr, ()); for (auto & subrouteInfo : m_subroutes) { // Interpolate values by zoom level. @@ -270,18 +271,49 @@ void RouteRenderer::UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallb double dist = kInvalidDistance; if (m_followingEnabled) dist = m_distanceFromBegin - subrouteInfo.m_subroute->m_baseDistance; - auto newArrowBorders = CalculateArrowBorders(screen, halfWidth, subrouteInfo, dist); - if (newArrowBorders.empty()) + + // We run asynchronous task to calculate new positions of route arrows. + auto const subrouteId = subrouteInfo.m_subrouteId; + auto const screenRect = screen.ClipRect(); + auto const screenScale = screen.GetScale(); + auto const subrouteLength = subrouteInfo.m_length; + auto subroute = subrouteInfo.m_subroute; + dp::DrapeRoutine::RunSequential([subrouteId, screenRect, screenScale, halfWidth, + subroute = std::move(subroute), subrouteLength, + dist, prepareCallback]() { - // Clear arrows. - subrouteInfo.m_arrowsData.reset(); - subrouteInfo.m_arrowBorders.clear(); - } - else if (!AreEqualArrowBorders(newArrowBorders, subrouteInfo.m_arrowBorders)) - { - subrouteInfo.m_arrowBorders = std::move(newArrowBorders); - callback(subrouteInfo.m_subrouteId, subrouteInfo.m_arrowBorders); - } + ASSERT(prepareCallback != nullptr, ()); + prepareCallback(subrouteId, CalculateArrowBorders(screenRect, screenScale, halfWidth, + subroute, subrouteLength, dist)); + }); + } +} + +void RouteRenderer::CacheRouteArrows(ScreenBase const & screen, dp::DrapeID subrouteId, + std::vector && arrowBorders, + CacheRouteArrowsCallback const & cacheCallback) +{ + ASSERT(cacheCallback != nullptr, ()); + auto const it = FindSubroute(m_subroutes, subrouteId); + if (it == m_subroutes.end()) + return; + + auto & subrouteInfo = *it; + + double zoom = 0.0; + float halfWidth = 0.0; + InterpolateByZoom(subrouteInfo.m_subroute, screen, halfWidth, zoom); + + if (arrowBorders.empty() || zoom < kArrowAppearingZoomLevel) + { + // Clear arrows. + subrouteInfo.m_arrowsData.reset(); + subrouteInfo.m_arrowBorders.clear(); + } + else if (!AreEqualArrowBorders(arrowBorders, subrouteInfo.m_arrowBorders)) + { + subrouteInfo.m_arrowBorders = std::move(arrowBorders); + cacheCallback(subrouteInfo.m_subrouteId, subrouteInfo.m_arrowBorders); } } @@ -435,8 +467,14 @@ void RouteRenderer::RenderSubroute(ref_ptr context, ref_ptr mng->GetParamsSetter()->Apply(context, prg, params); // Render buckets. - for (auto const & bucket : subrouteData->m_renderProperty.m_buckets) - bucket->Render(context, state.GetDrawAsLine()); + auto const & clipRect = screen.ClipRect(); + CHECK_EQUAL(subrouteData->m_renderProperty.m_buckets.size(), + subrouteData->m_renderProperty.m_boundingBoxes.size(), ()); + for (size_t i = 0; i < subrouteData->m_renderProperty.m_buckets.size(); ++i) + { + if (subrouteData->m_renderProperty.m_boundingBoxes[i].IsIntersect(clipRect)) + subrouteData->m_renderProperty.m_buckets[i]->Render(context, state.GetDrawAsLine()); + } } void RouteRenderer::RenderSubrouteArrows(ref_ptr context, ref_ptr mng, @@ -470,8 +508,15 @@ void RouteRenderer::RenderSubrouteArrows(ref_ptr context, r prg->Bind(); dp::ApplyState(context, prg, state); mng->GetParamsSetter()->Apply(context, prg, params); - for (auto const & bucket : subrouteInfo.m_arrowsData->m_renderProperty.m_buckets) - bucket->Render(context, state.GetDrawAsLine()); + + auto const & clipRect = screen.ClipRect(); + CHECK_EQUAL(subrouteInfo.m_arrowsData->m_renderProperty.m_buckets.size(), + subrouteInfo.m_arrowsData->m_renderProperty.m_boundingBoxes.size(), ()); + for (size_t i = 0; i < subrouteInfo.m_arrowsData->m_renderProperty.m_buckets.size(); ++i) + { + if (subrouteInfo.m_arrowsData->m_renderProperty.m_boundingBoxes[i].IsIntersect(clipRect)) + subrouteInfo.m_arrowsData->m_renderProperty.m_buckets[i]->Render(context, state.GetDrawAsLine()); + } } void RouteRenderer::RenderSubrouteMarkers(ref_ptr context, ref_ptr mng, diff --git a/drape_frontend/route_renderer.hpp b/drape_frontend/route_renderer.hpp index e676c2c0d3..c2e83cd757 100644 --- a/drape_frontend/route_renderer.hpp +++ b/drape_frontend/route_renderer.hpp @@ -29,6 +29,7 @@ extern std::string const kTransitStopInnerMarkerColor; class RouteRenderer final { public: + using PrepareRouteArrowsCallback = std::function &&)>; using CacheRouteArrowsCallback = std::function const &)>; using PreviewPointsRequestCallback = std::function; @@ -55,7 +56,10 @@ public: explicit RouteRenderer(PreviewPointsRequestCallback && previewPointsRequest); - void UpdateRoute(ScreenBase const & screen, CacheRouteArrowsCallback const & callback); + void PrepareRouteArrows(ScreenBase const & screen, PrepareRouteArrowsCallback const & prepareCallback); + void CacheRouteArrows(ScreenBase const & screen, dp::DrapeID subrouteId, + std::vector && arrowBorders, + CacheRouteArrowsCallback const & cacheCallback); void RenderRoute(ref_ptr context, ref_ptr mng, ScreenBase const & screen, bool trafficShown, FrameValues const & frameValues); diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 7703d954f0..847b89594a 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -13,7 +13,10 @@ #include "drape/glsl_types.hpp" #include "drape/texture_manager.hpp" +#include "geometry/mercator.hpp" + #include "base/logging.hpp" +#include "base/math.hpp" namespace df { @@ -116,7 +119,7 @@ float SideByNormal(glsl::vec2 const & normal, bool isLeft) void GenerateJoinsTriangles(glsl::vec3 const & pivot, std::vector const & normals, glsl::vec4 const & color, glsl::vec2 const & length, bool isLeft, - RouteShape::TGeometryBuffer & joinsGeometry) + RouteShape::GeometryBuffer & joinsGeometry) { size_t const trianglesCount = normals.size() / 3; for (size_t j = 0; j < trianglesCount; j++) @@ -125,9 +128,9 @@ void GenerateJoinsTriangles(glsl::vec3 const & pivot, std::vector co glsl::vec3 const len2 = glsl::vec3(length.x, length.y, SideByNormal(normals[3 * j + 1], isLeft)); glsl::vec3 const len3 = glsl::vec3(length.x, length.y, SideByNormal(normals[3 * j + 2], isLeft)); - joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j], len1, color)); - joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 1], len2, color)); - joinsGeometry.push_back(RouteShape::RV(pivot, normals[3 * j + 2], len3, color)); + joinsGeometry.emplace_back(pivot, normals[3 * j], len1, color); + joinsGeometry.emplace_back(pivot, normals[3 * j + 1], len2, color); + joinsGeometry.emplace_back(pivot, normals[3 * j + 2], len3, color); } } @@ -144,17 +147,17 @@ glsl::vec2 GetUV(m2::RectF const & texRect, glsl::vec2 const & uv) void GenerateArrowsTriangles(glsl::vec4 const & pivot, std::vector const & normals, m2::RectF const & texRect, std::vector const & uv, - bool normalizedUV, RouteShape::TArrowGeometryBuffer & joinsGeometry) + bool normalizedUV, RouteShape::ArrowGeometryBuffer & joinsGeometry) { size_t const trianglesCount = normals.size() / 3; for (size_t j = 0; j < trianglesCount; j++) { - joinsGeometry.push_back(RouteShape::AV(pivot, normals[3 * j], - normalizedUV ? GetUV(texRect, uv[3 * j]) : uv[3 * j])); - joinsGeometry.push_back(RouteShape::AV(pivot, normals[3 * j + 1], - normalizedUV ? GetUV(texRect, uv[3 * j + 1]) : uv[3 * j + 1])); - joinsGeometry.push_back(RouteShape::AV(pivot, normals[3 * j + 2], - normalizedUV ? GetUV(texRect, uv[3 * j + 2]) : uv[3 * j + 2])); + joinsGeometry.emplace_back(pivot, normals[3 * j], + normalizedUV ? GetUV(texRect, uv[3 * j]) : uv[3 * j]); + joinsGeometry.emplace_back(pivot, normals[3 * j + 1], + normalizedUV ? GetUV(texRect, uv[3 * j + 1]) : uv[3 * j + 1]); + joinsGeometry.emplace_back(pivot, normals[3 * j + 2], + normalizedUV ? GetUV(texRect, uv[3 * j + 2]) : uv[3 * j + 2]); } } @@ -178,7 +181,7 @@ void Subroute::AddStyle(SubrouteStyle const & style) void RouteShape::PrepareGeometry(std::vector const & path, m2::PointD const & pivot, std::vector const & segmentsColors, float baseDepth, - TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry) + std::vector> & geometryBufferData) { ASSERT(path.size() > 1, ()); @@ -195,13 +198,24 @@ void RouteShape::PrepareGeometry(std::vector const & path, m2::Point for (auto const & segment : segments) length += glsl::length(segment.m_points[EndPoint] - segment.m_points[StartPoint]); + geometryBufferData.emplace_back(GeometryBufferData()); + + uint32_t constexpr kMinVertices = 5000; + double constexpr kMinExtent = MercatorBounds::kRangeX / (1 << 10); + float depth = baseDepth; float const depthStep = kRouteDepth / (1 + segments.size()); for (auto i = static_cast(segments.size() - 1); i >= 0; i--) { + auto & geomBufferData = geometryBufferData.back(); + auto & geometry = geomBufferData.m_geometry; + UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr, (i < static_cast(segments.size()) - 1) ? &segments[i + 1] : nullptr); + geomBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[StartPoint])); + geomBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[EndPoint])); + // Generate main geometry. m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]), pivot, kShapeCoordScalar); @@ -224,23 +238,25 @@ void RouteShape::PrepareGeometry(std::vector const & path, m2::Point float const projRightStart = -segments[i].m_rightWidthScalar[StartPoint].y; float const projRightEnd = segments[i].m_rightWidthScalar[EndPoint].y; - geometry.push_back(RV(startPivot, glsl::vec2(0, 0), - glsl::vec3(startLength, 0, kCenter), segments[i].m_color)); - geometry.push_back(RV(startPivot, leftNormalStart, - glsl::vec3(startLength, projLeftStart, kLeftSide), segments[i].m_color)); - geometry.push_back(RV(endPivot, glsl::vec2(0, 0), - glsl::vec3(length, 0, kCenter), segments[i].m_color)); - geometry.push_back(RV(endPivot, leftNormalEnd, - glsl::vec3(length, projLeftEnd, kLeftSide), segments[i].m_color)); + geometry.emplace_back(startPivot, glsl::vec2(0, 0), + glsl::vec3(startLength, 0, kCenter), segments[i].m_color); + geometry.emplace_back(startPivot, leftNormalStart, + glsl::vec3(startLength, projLeftStart, kLeftSide), segments[i].m_color); + geometry.emplace_back(endPivot, glsl::vec2(0, 0), + glsl::vec3(length, 0, kCenter), segments[i].m_color); + geometry.emplace_back(endPivot, leftNormalEnd, + glsl::vec3(length, projLeftEnd, kLeftSide), segments[i].m_color); - geometry.push_back(RV(startPivot, rightNormalStart, - glsl::vec3(startLength, projRightStart, kRightSide), segments[i].m_color)); - geometry.push_back(RV(startPivot, glsl::vec2(0, 0), - glsl::vec3(startLength, 0, kCenter), segments[i].m_color)); - geometry.push_back(RV(endPivot, rightNormalEnd, - glsl::vec3(length, projRightEnd, kRightSide), segments[i].m_color)); - geometry.push_back(RV(endPivot, glsl::vec2(0, 0), - glsl::vec3(length, 0, kCenter), segments[i].m_color)); + geometry.emplace_back(startPivot, rightNormalStart, + glsl::vec3(startLength, projRightStart, kRightSide), segments[i].m_color); + geometry.emplace_back(startPivot, glsl::vec2(0, 0), + glsl::vec3(startLength, 0, kCenter), segments[i].m_color); + geometry.emplace_back(endPivot, rightNormalEnd, + glsl::vec3(length, projRightEnd, kRightSide), segments[i].m_color); + geometry.emplace_back(endPivot, glsl::vec2(0, 0), + glsl::vec3(length, 0, kCenter), segments[i].m_color); + + auto & joinsGeometry = geomBufferData.m_joinsGeometry; // Generate joins. if (segments[i].m_generateJoin && i < static_cast(segments.size()) - 1) @@ -287,13 +303,18 @@ void RouteShape::PrepareGeometry(std::vector const & path, m2::Point true, joinsGeometry); } + auto const verticesCount = geomBufferData.m_geometry.size() + geomBufferData.m_joinsGeometry.size(); + auto const extent = std::max(geomBufferData.m_boundingBox.SizeX(), geomBufferData.m_boundingBox.SizeY()); + if (verticesCount > kMinVertices && extent > kMinExtent) + geometryBufferData.emplace_back(GeometryBufferData()); + length = startLength; } } void RouteShape::PrepareArrowGeometry(std::vector const & path, m2::PointD const & pivot, m2::RectF const & texRect, float depthStep, float depth, - TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry) + GeometryBufferData & geometryBufferData) { ASSERT(path.size() > 1, ()); @@ -310,9 +331,14 @@ void RouteShape::PrepareArrowGeometry(std::vector const & path, m2:: float const depthInc = depthStep / (segments.size() + 1); for (size_t i = 0; i < segments.size(); i++) { + auto & geometry = geometryBufferData.m_geometry; + UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr, (i < segments.size() - 1) ? &segments[i + 1] : nullptr); + geometryBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[StartPoint])); + geometryBufferData.m_boundingBox.Add(glsl::FromVec2(segments[i].m_points[EndPoint])); + // Generate main geometry. m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]), pivot, kShapeCoordScalar); @@ -332,15 +358,17 @@ void RouteShape::PrepareArrowGeometry(std::vector const & path, m2:: glsl::vec2 const uvLeft = GetUV(tr, 0.5f, 0.0f); glsl::vec2 const uvRight = GetUV(tr, 0.5f, 1.0f); - geometry.push_back(AV(startPivot, glsl::vec2(0, 0), uvCenter)); - geometry.push_back(AV(startPivot, leftNormalStart, uvLeft)); - geometry.push_back(AV(endPivot, glsl::vec2(0, 0), uvCenter)); - geometry.push_back(AV(endPivot, leftNormalEnd, uvLeft)); + geometry.emplace_back(startPivot, glsl::vec2(0, 0), uvCenter); + geometry.emplace_back(startPivot, leftNormalStart, uvLeft); + geometry.emplace_back(endPivot, glsl::vec2(0, 0), uvCenter); + geometry.emplace_back(endPivot, leftNormalEnd, uvLeft); - geometry.push_back(AV(startPivot, rightNormalStart, uvRight)); - geometry.push_back(AV(startPivot, glsl::vec2(0, 0), uvCenter)); - geometry.push_back(AV(endPivot, rightNormalEnd, uvRight)); - geometry.push_back(AV(endPivot, glsl::vec2(0, 0), uvCenter)); + geometry.emplace_back(startPivot, rightNormalStart, uvRight); + geometry.emplace_back(startPivot, glsl::vec2(0, 0), uvCenter); + geometry.emplace_back(endPivot, rightNormalEnd, uvRight); + geometry.emplace_back(endPivot, glsl::vec2(0, 0), uvCenter); + + auto & joinsGeometry = geometryBufferData.m_joinsGeometry; // Generate joins. if (segments[i].m_generateJoin && i < segments.size() - 1) @@ -411,7 +439,7 @@ void RouteShape::PrepareArrowGeometry(std::vector const & path, m2:: void RouteShape::PrepareMarkersGeometry(std::vector const & markers, m2::PointD const & pivot, float baseDepth, - TMarkersGeometryBuffer & geometry) + MarkersGeometryBuffer & geometry) { ASSERT(!markers.empty(), ()); @@ -488,8 +516,7 @@ void RouteShape::CacheRouteArrows(ref_ptr context, std::vector const & borders, double baseDepthIndex, SubrouteArrowsData & routeArrowsData) { - TArrowGeometryBuffer geometry; - TArrowGeometryBuffer joinsGeometry; + GeometryBufferData geometryData; dp::TextureManager::SymbolRegion region; GetArrowTextureRegion(mng, region); auto state = CreateRenderState(gpu::Program::RouteArrow, DepthLayer::GeometryLayer); @@ -504,18 +531,23 @@ void RouteShape::CacheRouteArrows(ref_ptr context, std::vector points = CalculatePoints(polyline, b.m_startDistance, b.m_endDistance); ASSERT_LESS_OR_EQUAL(points.size(), polyline.GetSize(), ()); PrepareArrowGeometry(points, routeArrowsData.m_pivot, region.GetTexRect(), depthStep, - depth, geometry, joinsGeometry); + depth, geometryData); } - BatchGeometry(context, state, make_ref(geometry.data()), static_cast(geometry.size()), - make_ref(joinsGeometry.data()), static_cast(joinsGeometry.size()), - AV::GetBindingInfo(), routeArrowsData.m_renderProperty); + double constexpr kBoundingBoxScale = 1.2; + geometryData.m_boundingBox.Scale(kBoundingBoxScale); + + BatchGeometry(context, state, make_ref(geometryData.m_geometry.data()), + static_cast(geometryData.m_geometry.size()), + make_ref(geometryData.m_joinsGeometry.data()), + static_cast(geometryData.m_joinsGeometry.size()), + geometryData.m_boundingBox, AV::GetBindingInfo(), + routeArrowsData.m_renderProperty); } drape_ptr RouteShape::CacheRoute(ref_ptr context, - dp::DrapeID subrouteId, - SubrouteConstPtr subroute, size_t styleIndex, - int recacheId, + dp::DrapeID subrouteId, SubrouteConstPtr subroute, + size_t styleIndex, int recacheId, ref_ptr textures) { size_t startIndex; @@ -565,28 +597,34 @@ drape_ptr RouteShape::CacheRoute(ref_ptr subrouteData->m_recacheId = recacheId; subrouteData->m_distanceOffset = subroute->m_polyline.GetLength(startIndex); - TGeometryBuffer geometry; - TGeometryBuffer joinsGeometry; + std::vector> geometryBufferData; PrepareGeometry(points, subrouteData->m_pivot, segmentsColors, static_cast(subroute->m_baseDepthIndex * kDepthPerSubroute), - geometry, joinsGeometry); + geometryBufferData); auto state = CreateRenderState(subroute->m_style[styleIndex].m_pattern.m_isDashed ? gpu::Program::RouteDash : gpu::Program::Route, DepthLayer::GeometryLayer); state.SetColorTexture(textures->GetSymbolsTexture()); - BatchGeometry(context, state, make_ref(geometry.data()), static_cast(geometry.size()), - make_ref(joinsGeometry.data()), static_cast(joinsGeometry.size()), - RV::GetBindingInfo(), subrouteData->m_renderProperty); + double constexpr kBoundingBoxScale = 1.2; + for (auto & data : geometryBufferData) + { + data.m_boundingBox.Scale(kBoundingBoxScale); + BatchGeometry(context, state, make_ref(data.m_geometry.data()), + static_cast(data.m_geometry.size()), + make_ref(data.m_joinsGeometry.data()), + static_cast(data.m_joinsGeometry.size()), + data.m_boundingBox, RV::GetBindingInfo(), + subrouteData->m_renderProperty); + } + return subrouteData; } drape_ptr RouteShape::CacheMarkers(ref_ptr context, - dp::DrapeID subrouteId, - SubrouteConstPtr subroute, - int recacheId, - ref_ptr textures) + dp::DrapeID subrouteId, SubrouteConstPtr subroute, + int recacheId, ref_ptr textures) { if (subroute->m_markers.empty()) return nullptr; @@ -596,7 +634,7 @@ drape_ptr RouteShape::CacheMarkers(ref_ptrm_pivot = subroute->m_polyline.GetLimitRect().Center(); markersData->m_recacheId = recacheId; - TMarkersGeometryBuffer geometry; + MarkersGeometryBuffer geometry; auto const depth = static_cast(subroute->m_baseDepthIndex * kDepthPerSubroute + kMarkersDepth); PrepareMarkersGeometry(subroute->m_markers, markersData->m_pivot, depth, geometry); if (geometry.empty()) @@ -628,19 +666,27 @@ drape_ptr RouteShape::CacheMarkers(ref_ptr context, dp::RenderState const & state, ref_ptr geometry, uint32_t geomSize, ref_ptr joinsGeometry, uint32_t joinsGeomSize, - dp::BindingInfo const & bindingInfo, RouteRenderProperty & property) + m2::RectD const & boundingBox, dp::BindingInfo const & bindingInfo, + RouteRenderProperty & property) { - size_t const verticesCount = geomSize + joinsGeomSize; + auto verticesCount = geomSize + joinsGeomSize; if (verticesCount == 0) return; - uint32_t const kBatchSize = 5000; - dp::Batcher batcher(kBatchSize, kBatchSize); + uint32_t constexpr kMinBatchSize = 100; + uint32_t constexpr kMaxBatchSize = 65000; + uint32_t constexpr kIndicesScalar = 2; + + verticesCount = base::clamp(verticesCount, kMinBatchSize, kMaxBatchSize); + auto const indicesCount = base::clamp(verticesCount * kIndicesScalar, kMinBatchSize, kMaxBatchSize); + + dp::Batcher batcher(indicesCount, verticesCount); batcher.SetBatcherHash(static_cast(BatcherBucket::Routing)); - dp::SessionGuard guard(context, batcher, [&property](dp::RenderState const & state, - drape_ptr && b) + dp::SessionGuard guard(context, batcher, [&property, &boundingBox](dp::RenderState const & state, + drape_ptr && b) { property.m_buckets.push_back(std::move(b)); + property.m_boundingBoxes.push_back(boundingBox); property.m_state = state; }); diff --git a/drape_frontend/route_shape.hpp b/drape_frontend/route_shape.hpp index 32e9d221b2..29913ff57f 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -50,10 +50,6 @@ enum class RouteType : uint8_t struct RoutePattern { - bool m_isDashed = false; - double m_dashLength = 0.0; - double m_gapLength = 0.0; - RoutePattern() = default; RoutePattern(double dashLength, double gapLength) @@ -69,6 +65,10 @@ struct RoutePattern std::fabs(m_dashLength - pattern.m_dashLength) < kEps && std::fabs(m_gapLength - pattern.m_gapLength) < kEps; } + + bool m_isDashed = false; + double m_dashLength = 0.0; + double m_gapLength = 0.0; }; enum class SubrouteStyleType @@ -79,14 +79,8 @@ enum class SubrouteStyleType struct SubrouteStyle { - df::ColorConstant m_color; - df::ColorConstant m_outlineColor; - df::RoutePattern m_pattern; - size_t m_startIndex = 0; - size_t m_endIndex = 0; - SubrouteStyle() = default; - SubrouteStyle(df::ColorConstant const & color) + explicit SubrouteStyle(df::ColorConstant const & color) : m_color(color) , m_outlineColor(color) {} @@ -106,16 +100,19 @@ struct SubrouteStyle , m_pattern(pattern) {} - bool operator == (SubrouteStyle const & style) const + bool operator==(SubrouteStyle const & style) const { return m_color == style.m_color && m_outlineColor == style.m_outlineColor && m_pattern == style.m_pattern; } - bool operator != (SubrouteStyle const & style) const - { - return !operator == (style); - } + bool operator!=(SubrouteStyle const & style) const { return !operator==(style); } + + df::ColorConstant m_color; + df::ColorConstant m_outlineColor; + df::RoutePattern m_pattern; + size_t m_startIndex = 0; + size_t m_endIndex = 0; }; // Colored circle on the subroute. @@ -157,11 +154,13 @@ using SubrouteConstPtr = std::shared_ptr; struct RouteRenderProperty { - dp::RenderState m_state; - std::vector> m_buckets; RouteRenderProperty() : m_state(CreateRenderState(gpu::Program::Route, DepthLayer::GeometryLayer)) {} + + dp::RenderState m_state; + std::vector> m_buckets; + std::vector m_boundingBoxes; }; struct BaseSubrouteData @@ -196,11 +195,11 @@ class RouteShape { public: using RV = gpu::RouteVertex; - using TGeometryBuffer = buffer_vector; + using GeometryBuffer = buffer_vector; using AV = gpu::SolidTexturingVertex; - using TArrowGeometryBuffer = buffer_vector; + using ArrowGeometryBuffer = buffer_vector; using MV = gpu::RouteMarkerVertex; - using TMarkersGeometryBuffer = buffer_vector; + using MarkersGeometryBuffer = buffer_vector; static drape_ptr CacheRoute(ref_ptr context, dp::DrapeID subrouteId, SubrouteConstPtr subroute, @@ -218,20 +217,30 @@ public: SubrouteArrowsData & routeArrowsData); private: + template + struct GeometryBufferData + { + GeometryBufferData() + : m_boundingBox(m2::RectD::GetEmptyRect()) + {} + + GeometryBufferType m_geometry; + GeometryBufferType m_joinsGeometry; + m2::RectD m_boundingBox; + }; static void PrepareGeometry(std::vector const & path, m2::PointD const & pivot, std::vector const & segmentsColors, float baseDepth, - TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry); + std::vector> & geometryBufferData); static void PrepareArrowGeometry(std::vector const & path, m2::PointD const & pivot, m2::RectF const & texRect, float depthStep, float depth, - TArrowGeometryBuffer & geometry, - TArrowGeometryBuffer & joinsGeometry); + GeometryBufferData & geometryBufferData); static void PrepareMarkersGeometry(std::vector const & markers, m2::PointD const & pivot, float baseDepth, - TMarkersGeometryBuffer & geometry); + MarkersGeometryBuffer & geometry); static void BatchGeometry(ref_ptr context, dp::RenderState const & state, ref_ptr geometry, uint32_t geomSize, ref_ptr joinsGeometry, - uint32_t joinsGeomSize, dp::BindingInfo const & bindingInfo, - RouteRenderProperty & property); + uint32_t joinsGeomSize, m2::RectD const & boundingBox, + dp::BindingInfo const & bindingInfo, RouteRenderProperty & property); }; } // namespace df diff --git a/iphone/Maps/Classes/MapsAppDelegate.mm b/iphone/Maps/Classes/MapsAppDelegate.mm index ace8e8102d..3e93d920a2 100644 --- a/iphone/Maps/Classes/MapsAppDelegate.mm +++ b/iphone/Maps/Classes/MapsAppDelegate.mm @@ -575,7 +575,7 @@ using namespace osm_auth_ios; if ([AppInfo sharedInfo].openGLDriver == MWMOpenGLDriverMetalPre103) { m2::PointU const size = ((EAGLView *)self.mapViewController.view).pixelSize; - f.OnRecoverSurface(static_cast(size.x), static_cast(size.y)); + f.OnRecoverSurface(static_cast(size.x), static_cast(size.y), true /* recreateContextDependentResources */); } [MWMLocationManager applicationDidBecomeActive]; [MWMSearch addCategoriesToSpotlight]; diff --git a/map/framework.cpp b/map/framework.cpp index b7a19375ee..bb584ca1c1 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -390,7 +390,8 @@ void Framework::Migrate(bool keepDownloaded) { m_drapeEngine->SetRenderingEnabled(); OnRecoverSurface(m_currentModelView.PixelRectIn3d().SizeX(), - m_currentModelView.PixelRectIn3d().SizeY()); + m_currentModelView.PixelRectIn3d().SizeY(), + true /* recreateContextDependentResources */); } InvalidateRect(MercatorBounds::FullRect()); } @@ -1910,11 +1911,11 @@ void Framework::CreateDrapeEngine(ref_ptr contextFac benchmark::RunGraphicsBenchmark(this); } -void Framework::OnRecoverSurface(int width, int height) +void Framework::OnRecoverSurface(int width, int height, bool recreateContextDependentResources) { if (m_drapeEngine) { - m_drapeEngine->Update(width, height); + m_drapeEngine->RecoverSurface(width, height, recreateContextDependentResources); InvalidateUserMarks(); @@ -2447,21 +2448,20 @@ df::SelectionShape::ESelectedObject Framework::OnTapEventImpl(TapEvent const & t } FeatureID featureTapped = tapInfo.m_featureTapped; - if (!featureTapped.IsValid()) featureTapped = FindBuildingAtPoint(tapInfo.m_mercator); bool showMapSelection = false; - if (featureTapped.IsValid()) - { - FillFeatureInfo(featureTapped, outInfo); - showMapSelection = true; - } - else if (tapInfo.m_isLong || tapEvent.m_source == TapEvent::Source::Search) + if (tapInfo.m_isLong || tapEvent.m_source == TapEvent::Source::Search) { FillPointInfo(tapInfo.m_mercator, {} /* customTitle */, outInfo); showMapSelection = true; } + else if (featureTapped.IsValid()) + { + FillFeatureInfo(featureTapped, outInfo); + showMapSelection = true; + } if (showMapSelection) { diff --git a/map/framework.hpp b/map/framework.hpp index 7fda4c5469..c6c223fe2d 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -510,7 +510,7 @@ public: void SetRenderingEnabled(ref_ptr contextFactory = nullptr); void SetRenderingDisabled(bool destroySurface); - void OnRecoverSurface(int width, int height); + void OnRecoverSurface(int width, int height, bool recreateContextDependentResources); void OnDestroySurface(); private: diff --git a/shaders/GL/area3d_outline.vsh.glsl b/shaders/GL/area3d_outline.vsh.glsl index 118910a426..c5a04b0df9 100644 --- a/shaders/GL/area3d_outline.vsh.glsl +++ b/shaders/GL/area3d_outline.vsh.glsl @@ -19,6 +19,10 @@ void main() pos.xyw = (pos * u_projection).xyw; pos.z = a_position.z * u_zScale; gl_Position = u_pivotTransform * pos; +#ifdef VULKAN + gl_Position.y = -gl_Position.y; + gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5; +#endif #ifdef ENABLE_VTF v_color = texture2D(u_colorTex, a_colorTexCoords);