Tiger Lake odhaleno: architektura a novinky. Výkon zlepší hlavně takty, IPC stouplo málo

14. 8. 2020

Sdílet

 Autor: Intel
Intel konečně odhalil detaily nových procesorů založených na procesu 10nm SuperFin. Přinesou PCIe 4.0, pamětiLPDDR5, přehrávání AV1 a hlavně vysoké frekvence, takže jednovláknový výkon by mohl výrazně předstihnout vše, co tu bylo dosud.

Včera Intel odhalil technologické novinky napříč svými procesory, připravovanými grafikami, výrobními procesy i dalšími produkty z tzv. Intel Architecture Day 2020. Už jsme zde probírali odhalení výkonných grafik Intel Xe HPG, které už budou obsahovat jednotky akcelerující ray tracing a konkurovat tak výkonným GeForce a Radeonům. Ale Intel zejména odhalil architekturu a další vnitřnosti nových 10nm+ procesorů Tiger Lake, alias Core 11. generace.

Nové jádro Willow Cove: nové cache, IPC nakonec nenaroste dramaticky

Procesory Tiger Lake v jejich současné formě jsou čtyřjádrové procesory pro notebooky, které se budou vyrábět klasicky v provedení BGA pájeném na desku. Integrována jsou v nich CPU jádra s novou architekturou, současně také GPU s 96 EUP768 shadery nové architektury Xe LP (této architektuře, určené i pro samostatné karty, se budeme věnovat samostatně) a rovněž nová konektivita a výbava.

Tiger Lake obsahuje jádra s kódovým označením Willow Cove. Jsou odlišná od jádra Ice Lake, které bylo první výrazně inovovanou architekturou Intelu od Skylake a loni (2019) přineslo zhruba o 18 % vyšší IPC – tedy cca o 18 % vyšší výkon na 1 MHz frekvence.

Willow Cove je oproti Sunny Cove nová architektura, ale změny jsou dílčí a značná část je podobná či stejná. Kvůli tomuto nemá nakonec Tiger Lake/Willow Cove proti Ice Lake/Sunny Cove nějak brutálně zvýšené IPC, jak možná někdo čekal. Nárůst bude tentokrát nižší (bližší „tickům“, pro pamětníky), další velký skok nastane až za rok s architekturou Golden Cove v procesorech Alder Lake.

Hlavní zdroj výkonu: opět vysoké frekvence

Jádro Willow Cove bude mít i tak podle Intelu o 10–20 % vyšší výkon, než Sunny Cove, ale nebude to díky takto vysokému IPC, naopak většinu rozdílu bude dělat vyšší frekvence, kterou zajistil nový vylepšený výrobní proces 10SF (10nm SuperFin). I ten byl odhalen včera a čím je tak speciální, jsme popisovali v tomto článku:

Tip: 10nm proces Intelu zpět ve hře. Technologie SuperFin masivně zlepší takty, problémy pryč?

Galerie: Intel Architecture Day 2020: vylepšený 10nm proces SuperFin (10SF)

Proces 10SF díky předělané struktuře tranzistorů a dalších elementů přináší velká zlepšení dosažitelné frekvence (výkonu) a do značné míry zdá se odčiní neduhy, které v tomto první verze 10nm procesu měla. Zatímco Ice Lake končilo frekvencí někde u 4,0 GHz, Tiger Lake by mohlo spět (byť třeba ne nutně úplně dospět) až skoro ke 5,0 GHz.

Jádro bude při stejném napětí dosahovat vyšší frekvence, ale současně umožní zvednout napětí výš a posunout takt ještě o to dál. Zde je to názorně na grafu.

Vyšší napětí by samozřejmě ovšem také vedlo k určitému navýšení spotřeby. Je možné, že na nejvyšších jednojádrových boostech bude příkon Tiger Laku poměrně vysoký, ovšem to může být i u 14nm CPU nebo u Ryzenů od konkurence. Intel mimochodem uvádí, že Tiger Lake je navrženo pro spotřeby v rozsahu od 10 W do 65 W.

Backend a frontend jádra vesměs beze změn

Intel zřejmě zachoval prakticky beze změn (tedy až na to, že jsou nyní použité tranzistory na bázi SuperFinu) většinu jádra. Willow Cove by tedy mělo mít stejné počty výpočetních jednotek (ALU, SIMD/FPU, load/store) jako Sunny Cove, stejně jako jeho prefetchery a prediktory větvení. Ani hloubky out-of-order front se asi neměnily.

Cache: zvětšení L2 o 150 %, L3 o polovinu

Ovšem výkon (IPC) může zvýšit paměťový subsystém a cache, kde změny nastaly. Zejména jsou to mezipaměti CPU. Intel nyní potvrdil, co již dříve prosáklo: Tiger Lake (Willow Cove) má výrazně větší L2 a L3 cache.

Největším upgradem je asi zvětšení L2 cache, která je jako vždy privátní pro každé jádro. Zatímco Skylake obsahovalo 256 KB na jádro a Ice Lake (Sunny Cove) 512 KB, zde už má jádro 1,25 MB. Je možné, že její latence kvůli tomu trochu stoupla proti 12 cyklům u Skylake a 13 cyklům u Sunny Cove. Intel ale přesný počet cyklů nesdělil.

L2 cache se také změnila z inkluzivní (tedy obsahující kopii všech dat v L1) na neinkluzivní. Toto by mělo o něco zlepšit výkon, ale také vyžaduje logiku navíc pro řešení koherence (synchronizace). Asociativita cache je jinak 20-cestná (512KB u Ice Lake je 8-way asociativní, totéž 512B L2 cache Zenu/Zenu 2).

Také L3 se zvětšila. Předchozí procesory obsahovaly 2MB blok L3 cache pro každé jádro, což se pak v čipu spojuje dohromady (některé modely, například Core i5, to ale mohly mít ořezané třeba na 1,5 MB/jádro). U Tiger Lake Intel zvýšil kapacitu na 3 MB pro každý blok, takže čtyřjádro bude mít celkově už 12 MB L3 cache.

Asociativia byla ale snížena, zatímco dřívější cache s 2MB blokem byly 16-way, L3 cache s 3MB blokem je u Tiger Lake jen 12-way (místo 24-way). Rovněž L3 cache je jinak už neinkluzivní , zatímco dříve Intel používal inkluzivní cache (obsahovala kopie dat z L1 a L2). Latenci L3 cache Intel opět nesdělil.

Zlepšení IPC o 4–6 %?

Je možné, že v některých úlohách, která byly kapacitami cache limitované, toto povede k výrazným zlepšením výkonu. V průměru ale budou zisky mírné. Větší cache by podle AnandTech údajně měly přinášet „nízké jednociferné“ (1–3 %) zlepšení. Celkově i s dalšími vlivy by jádro Willow Cove mohlo mít IPC vyšší o „střední jednociferná procenta“, čímž se míní 4–6 %. V průměru by pak mohlo být IPC asi o 25 % lepší v porovnání s architekturou Skylake.

Paměti: LPDDR5 s propustností až 86,4 GB/s

Tiger Lake podporuje paměti DDR4-3200 (až 64 GB) a LPDDR4X-4266 (až 32 GB); ty by dávaly teoretickou propustnost 51,2, respektive 62,8 GB/s. Ovšem k tomu Tiger Lake poprvé umí už i paměti LPDDR5. Po konfliktních zprávách (chvíli se zdálo, že LPDDR5 bude, pak že nebude) se tedy tato nová technologie potvrdila.

Čtyřjádrové Tiger Lake-U bude podporovat LPDDR5-5400, což při 128bitovém řadiči (z desktopového pohledu dvoukanálovém, ale u LPDDR to znamená čtyři 32bitové kanály) dává teoretickou propustnost už 86,4 GB/s. Integrovanému GPU by to mělo hodně chutnat. Jak často budou notebooky s Tiger Lake LPDDR5 používat, ale není jasné. Tyto paměti jsou údajně dost drahé, takže častější možná ze začátku bude klasická LPDDR4X (nebo DDR4).

Dvojnásobná kapacita interní sběrnice

Ovšem nejen paměťová propustnost bude vyšší. Také v rámci čipu bude zesílena propustnost interní sběrnice ringbus, která propojuje jádra (přesněji jejich bloky L3 cache), systém agent, paměťový řadič, integrované GPU a northbridge. Je stále použitá obousměrná prstencová sběrnice, ale místo použití jedné byla zdvojnásobená (dvojitý ringbus), takže lze přednést 2× 32 bajtů za jeden cyklus duplexně. Tam, kde byly propustnost limitující, se tedy může zvýšit výkon.

10nm procesory Intel Tiger lake odhalení architektury schema Schéma procesoru Intel Tiger Lake (Zdroj: Intel)

Total Memory Encryption

Tiger Lake dále také podporuje kompletní šifrování paměti RAM nazvané Total Memory Encryption (TME). To je pro běžící software transparentní, ale znemožňuje tzv. cold attack, kdy se po vypnutí vytáhne modul RAM z notebooku a přečtou se z něj data. Jde o obdobu šifrování RAM, které poskytují procesory AMD Ryzen Pro a Epyc.

Control-Flow Enforcement Technology

Pro zvýšení bezpečnosti má Tiger Lake i další novinku, Control-Flow Enforcement Technology. Jde o ochranu před tzv. Return-oriented a Jump-oriented útoky. Tiger Lake používá stínové stacky (Shadow Stacks) a kontrolování paměťových stránek pro ochranu před útoky týkajícími se návratové adresy.

Proti útokům spočívajícím v nesprávných cílech skoků a volání je přidaná technologie Indirect Branch Tracking. Ale ta nebude fungovat automaticky, využije ji jen nově zkompilovaný software, jelikož vyžaduje použití nových instrukcí. Tyto novinky pomohou ochránit běžící operační systém před některými zranitelnostmi a ztíží práci hackerům.

Článek pokračuje na další straně informacemi o výbavě a konektivitě procesorů Tiger Lake.

Galerie: Odhalení procesorů Intel Tiger Lake: detaily, technologie, architektura

PCI Express 4.0, Thunderbolt 4, USB4, dekodér AV1…

Mimo samotná jádra CPU a výkonnou integrovanou grafiku Gen12/Intel Xe LP má Tiger Lake různou novou výbavu. O LPDDR5 už byla řeč, ale Tiger Lake je také první procesor Intelu, který podporuje PCI Express 4.0. Paradoxně jde přitom o procesor pro notebooky, zatímco AMD PCI Express 4.0 nabízí jen v serverechvýkonném desktopu.

Nevíme ještě, kolik linek PCIe 4.0 Tiger Lake poskytuje, u Tiger Lake-U se čtyřmi jádry by jich mohlo asi být až osm (×4 pro SSD, další ×4 pro samostatné GPU). Je zajímavé, že podle Intelu toto nezvýšilo spotřebu, údajně se podařilo řadič dostat na zhruba stejný příkon, jako by měl blok pro PCIe 3.0.

Zdá se, že řadič PCI Expressu je také konečně v procesoru, zatímco dosud ho procesory řady U měly v čipsetu připájeném na pouzdru. Komunikace s SSD tak nabírala zpoždění, Intel uvádí, že při připojení SSD či GPU přímo k CPU je latence až o 100 ns lepší.

Osmijádrové Tiger Lake-H

Intel již naznačil, že kromě čtyřjádrového Tiger Lake-U by měla vzniknout také výkonnější verze (asi Tiger Lake-H) pro výkonnější notebooky. Ta by asi měla mít osm jader (to říkají i úniky), jelikož dle Intelu Tiger Lake „může nést až 24 MB L3 cache“, zatímco čtyřjádro má 12 MB. Tento procesor by také asi mohl poskytovat plných 16 linek PCI Express 4.0 pro připojení samostatného GPU.

Vzorek procesoru Intel Tiger Lake ukazany na CES 2020 3 Vzorek procesoru Intel Tiger Lake ukázaný na CES 2020
Ukázka procesoru Intel Tiger Lake-U na CES 2020, grafika Xe DG1, Project Athena (Fotogalerie)

IPU6 a akcelerátor umělé inteligence GNA 2.0

Tiger Lake také obsahuje vylepšený akcelerátor GNA 2.0 (Gaussian and Neural Accelerator), pro operace používané například k rozpoznávání řeči s nízkou spotřebou energie (tedy i ve standby) nebo omezení šumu v mikrofonu. Tento akcelerátor dokáže údajně poskytnout výkon asi 1 giga operace za sekundu na příkon 1 mW, maximálně 38 GOPS při spotřebě 38 mW.

Také jednotka pro zpracování obrazu z kamery/kamer byla vylepšena. Její generace IPU6 podporuje stejně jako v Ice Lake až šest kamer, ale Tiger Lake má údajně podporovat až 42megapixelové senzory a 4K video s frekvencí až 90 FPS. Toto ale asi bude až u výkonnějších modelů (Tiger Lake-H?), pro Tiger Lake-U má nižší výkon, schopný zpracovat 27 megapixelů a 4K video při 30 snímcích za sekundu.

Thunderbolt 4, USB4

Nedávno Intel oficiálně oznámil či uvedl technologii Thunderbolt 4. Procesory Tiger Lake jsou první, které pro ni mají podporu. Řadič je integrovaný na čipu, přičemž by měly být podporované až čtyři porty TB4 (dva na každé straně notebooku) s 40Gb/s propustností.

Současně s Thunderboltem 4 podporuje Tiger Lake i USB4.

8K obrazovky

Porty USB-C poskytované řadičem Thunderboltu bude možné použít k obrazovému výstupu. Kromě nich umí Tiger Lake i výstup HDMI 2.0 (HDMI 2.1 ještě ne) a DisplayPort 1.4; interní panel notebooků použije eDP. Až čtyři obrazovky mohou být připojené naráz.

Je možné použít adaptivní obnovování VESA Adaptive-Sync/FreeSync, je také podporováno HDR10, 12bitové barvy s gamutem BT2020 a maximální snímková frekvence (asi s 1080p LCD) je až 360 Hz. Rozlišení je maximálně podporováno 8K (7680 × 4320 bodů).

Podpora AV1

Také video bude možné přehrávat až v rozlišení 8K (dokonce s 60 snímky za sekundu). Je podporováno i přehrávání HDR a Dolby Vision, celá video pipeline podporuje práci s 12bitovým barevnými hodnotami. Intel také uvádí, že výkon dekodérů i enkodérů hardwarového bloku je dvojnásobný proti Ice Lake.

Asi nejhmatatelnější novinka je, že multimediální blok jako první podporuje hardwarové dekódování video formátu AV1.

Galerie: Odhalení procesorů Intel Tiger Lake: detaily, technologie, architektura

Vydání procesorů bude 2. září

Pokud se na procesory Tiger Lake (a notebooky s nimi) těšíte, nachystejte se na 2. září. Intel uvádí, že ten den proběhne virtuální tisková konference/přenos a „event“, během kterého budou procesory finálně uvedeny na trh. Akce začne v 18:00 a měla by být přenášena.

Intel by měl v tento den potvrdit parametry procesorů, které nyní ještě nesdělil, zřejmě se dočkáme i benchmarků a k tomuto dni by mohly přijít na trh první notebooky s Tiger Lake.

Zdroje: Intel, AnandTech

Autor článku

Redaktor portálu Cnews.cz. Zaměřuje se na procesory, mobilní SoC, grafické karty, disky a další počítačový hardware. Profil autora →

'; document.getElementById('preroll-iframe').onload = function () { setupIframe(); } prerollContainer = document.getElementsByClassName('preroll-container-iframe')[0]; } function setupIframe() { prerollDocument = document.getElementById('preroll-iframe').contentWindow.document; let el = prerollDocument.createElement('style'); prerollDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:20px;right:25px}"; videoContent = prerollDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('PREROLL sound allowed'); // setUpIMA(true); videoContent.volume = 1; videoContent.muted = false; setUpIMA(); }).catch(function () { console.log('PREROLL sound forbidden'); videoContent.volume = 0; videoContent.muted = true; setUpIMA(); }); } } function setupDimensions() { prerollWidth = Math.min(iinfoPrerollPosition.offsetWidth, 480); prerollHeight = Math.min(iinfoPrerollPosition.offsetHeight, 320); } function setUpIMA() { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Preroll advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = prerollWidth; // adsRequest.linearAdSlotHeight = prerollHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. prerollDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( prerollDocument.getElementById('adContainer'), videoContent); } function unmutePrerollAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); prerollDocument.getElementById('adMuteBtn').innerHTML = ''; } } function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(prerollWidth, prerollHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } function onAdEvent(adEvent) { const ad = adEvent.getAd(); console.log('Preroll event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: if (!ad.isLinear()) { videoContent.play(); } prerollDocument.getElementById('adContainer').style.width = '100%'; prerollDocument.getElementById('adContainer').style.maxWidth = '640px'; prerollDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); if (ad.isLinear()) { intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } prerollDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (prerollLastError === 303) { playYtVideo(); } break; case google.ima.AdEvent.Type.COMPLETE: if (ad.isLinear()) { clearInterval(intervalTimer); } playYtVideo(); break; } } function onAdError(adErrorEvent) { console.log(adErrorEvent.getError()); prerollLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { playYtVideo(); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoPrerollPosition.remove(); playPrerollAd(); } else { return false; } adVolume = 1; return true; } function onContentPauseRequested() { videoContent.pause(); } function onContentResumeRequested() { videoContent.play(); } function onActiveView() { if (prerollContainer) { const containerOffset = prerollContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (prerollPaused) { adsManager.resume(); prerollPaused = false; } return true; } else { if (!prerollPaused) { adsManager.pause(); prerollPaused = true; } } } return false; } function playYtVideo() { iinfoPrerollPosition.remove(); youtubeIframe.style.display = 'block'; youtubeIframe.src += '&autoplay=1&mute=1'; } }
'; document.getElementById('outstream-iframe').onload = function () { setupIframe(); } replayScreen = document.getElementById('iinfoOutstreamReplay'); iinfoOutstreamPosition = document.getElementById('iinfoOutstreamPosition'); outstreamContainer = document.getElementsByClassName('outstream-container')[0]; setupReplayScreen(); } function setupIframe() { outstreamDocument = document.getElementById('outstream-iframe').contentWindow.document; let el = outstreamDocument.createElement('style'); outstreamDocument.head.appendChild(el); el.innerText = "#adContainer>div:nth-of-type(1),#adContainer>div:nth-of-type(1) > iframe { width: 99% !important;height: 99% !important;max-width: 100%;}#videoContent,body{ width:100vw;height:100vh}body{ font-family:'Helvetica Neue',Arial,sans-serif}#videoContent{ overflow:hidden;background:#000}#adMuteBtn{ width:35px;height:35px;border:0;background:0 0;display:none;position:absolute;fill:rgba(230,230,230,1);bottom:-5px;right:25px}"; videoContent = outstreamDocument.getElementById('contentElement'); videoContent.style.display = 'none'; videoContent.volume = 1; videoContent.muted = false; if ( location.href.indexOf('rejstriky.finance.cz') !== -1 || location.href.indexOf('finance-rejstrik') !== -1 || location.href.indexOf('firmy.euro.cz') !== -1 || location.href.indexOf('euro-rejstrik') !== -1 || location.href.indexOf('/rejstrik/') !== -1 || location.href.indexOf('/rejstrik-firem/') !== -1) { outstreamDirectPlayed = true; soundAllowed = true; iinfoVastUrlIndex = 0; } if (!outstreamDirectPlayed) { console.log('OUTSTREAM direct'); setUpIMA(true); } else { if (soundAllowed) { const playPromise = videoContent.play(); if (playPromise !== undefined) { playPromise.then(function () { console.log('OUTSTREAM sound allowed'); setUpIMA(false); }).catch(function () { console.log('OUTSTREAM sound forbidden'); renderBanner(); }); } } else { renderBanner(); } } } function getWrapper() { let articleWrapper = document.querySelector('.rs-outstream-placeholder'); // Outstream Placeholder from RedSys manipulation if (articleWrapper && articleWrapper.style.display !== 'block') { articleWrapper.innerHTML = ""; articleWrapper.style.display = 'block'; } // Don't render OutStream on homepages if (articleWrapper === null) { if (document.querySelector('body.p-index')) { return null; } } if (articleWrapper === null) { articleWrapper = document.getElementById('iinfo-outstream'); } if (articleWrapper === null) { articleWrapper = document.querySelector('.layout-main__content .detail__article p:nth-of-type(6)'); } if (articleWrapper === null) { // Euro, Autobible, Zdravi articleWrapper = document.querySelector('.o-article .o-article__text p:nth-of-type(6)'); } if (articleWrapper === null) { articleWrapper = document.getElementById('sidebar'); } if (!articleWrapper) { console.error("Outstream wrapper of article was not found."); } return articleWrapper; } function setupDimensions() { outstreamWidth = Math.min(iinfoOutstreamPosition.offsetWidth, 480); outstreamHeight = Math.min(iinfoOutstreamPosition.offsetHeight, 320); } /** * Sets up IMA ad display container, ads loader, and makes an ad request. */ function setUpIMA(direct) { google.ima.settings.setDisableCustomPlaybackForIOS10Plus(true); google.ima.settings.setLocale('cs'); google.ima.settings.setNumRedirects(10); // Create the ad display container. createAdDisplayContainer(); // Create ads loader. adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Listen and respond to ads loaded and error events. adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); // An event listener to tell the SDK that our content video // is completed so the SDK can play any post-roll ads. const contentEndedListener = function () { adsLoader.contentComplete(); }; videoContent.onended = contentEndedListener; // Request video ads. const adsRequest = new google.ima.AdsRequest(); if (direct) { adsRequest.adTagUrl = directVast; console.log('Outstream DIRECT CAMPAING advert: ' + directVast); videoContent.muted = true; videoContent.volume = 0; outstreamDirectPlayed = true; } else { adsRequest.adTagUrl = iinfoVastUrls[iinfoVastUrlIndex]; console.log('Outstream advert: ' + iinfoVastUrls[iinfoVastUrlIndex]); videoContent.muted = false; videoContent.volume = 1; } // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. // adsRequest.linearAdSlotWidth = outstreamWidth; // adsRequest.linearAdSlotHeight = outstreamHeight; adsRequest.nonLinearAdSlotWidth = 0; adsRequest.nonLinearAdSlotHeight = 0; adsLoader.requestAds(adsRequest); } function setupReplayScreen() { replayScreen.addEventListener('click', function () { iinfoOutstreamPosition.remove(); iinfoVastUrlIndex = 0; outstreamInit(); }); } /** * Sets the 'adContainer' div as the IMA ad display container. */ function createAdDisplayContainer() { // We assume the adContainer is the DOM id of the element that will house // the ads. outstreamDocument.getElementById('videoContent').style.display = 'none'; adDisplayContainer = new google.ima.AdDisplayContainer( outstreamDocument.getElementById('adContainer'), videoContent); } function unmuteAdvert() { adVolume = !adVolume; if (adVolume) { adsManager.setVolume(0.3); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } else { adsManager.setVolume(0); outstreamDocument.getElementById('adMuteBtn').innerHTML = ''; } } /** * Loads the video content and initializes IMA ad playback. */ function playAds() { // Initialize the container. Must be done through a user action on mobile // devices. videoContent.load(); adDisplayContainer.initialize(); // setupDimensions(); try { // Initialize the ads manager. Ad rules playlist will start at this time. adsManager.init(1920, 1080, google.ima.ViewMode.NORMAL); // Call play to start showing the ad. Single video and overlay ads will // start at this time; the call will be ignored for ad rules. adsManager.start(); // window.addEventListener('resize', function (event) { // if (adsManager) { // setupDimensions(); // adsManager.resize(outstreamWidth, outstreamHeight, google.ima.ViewMode.NORMAL); // } // }); } catch (adError) { // An error may be thrown if there was a problem with the VAST response. // videoContent.play(); } } /** * Handles the ad manager loading and sets ad event listeners. * @param { !google.ima.AdsManagerLoadedEvent } adsManagerLoadedEvent */ function onAdsManagerLoaded(adsManagerLoadedEvent) { // Get the ads manager. const adsRenderingSettings = new google.ima.AdsRenderingSettings(); adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true; adsRenderingSettings.loadVideoTimeout = 12000; // videoContent should be set to the content video element. adsManager = adsManagerLoadedEvent.getAdsManager(videoContent, adsRenderingSettings); // Add listeners to the required events. adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, onContentPauseRequested); adsManager.addEventListener( google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, onContentResumeRequested); adsManager.addEventListener( google.ima.AdEvent.Type.ALL_ADS_COMPLETED, onAdEvent); // Listen to any additional events, if necessary. adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, onAdEvent); adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, onAdEvent); playAds(); } /** * Handles actions taken in response to ad events. * @param { !google.ima.AdEvent } adEvent */ function onAdEvent(adEvent) { // Retrieve the ad from the event. Some events (for example, // ALL_ADS_COMPLETED) don't have ad object associated. const ad = adEvent.getAd(); console.log('Outstream event: ' + adEvent.type); switch (adEvent.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to // determine whether the ad is a video ad or an overlay. if (!ad.isLinear()) { // Position AdDisplayContainer correctly for overlay. // Use ad.width and ad.height. videoContent.play(); } outstreamDocument.getElementById('adContainer').style.width = '100%'; outstreamDocument.getElementById('adContainer').style.maxWidth = '640px'; outstreamDocument.getElementById('adContainer').style.height = '360px'; break; case google.ima.AdEvent.Type.STARTED: window.addEventListener('scroll', onActiveView); // This event indicates the ad has started - the video player // can adjust the UI, for example display a pause button and // remaining time. if (ad.isLinear()) { // For a linear ad, a timer can be started to poll for // the remaining time. intervalTimer = setInterval( function () { // Example: const remainingTime = adsManager.getRemainingTime(); // adsManager.pause(); }, 300); // every 300ms } outstreamDocument.getElementById('adMuteBtn').style.display = 'block'; break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: if (ad.isLinear()) { clearInterval(intervalTimer); } if (outstreamLastError === 303) { if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } } break; case google.ima.AdEvent.Type.COMPLETE: // This event indicates the ad has finished - the video player // can perform appropriate UI actions, such as removing the timer for // remaining time detection. if (ad.isLinear()) { clearInterval(intervalTimer); } if (isBanner) { renderBanner(); } else { replayScreen.style.display = 'flex'; } break; } } /** * Handles ad errors. * @param { !google.ima.AdErrorEvent } adErrorEvent */ function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); outstreamLastError = adErrorEvent.getError().getErrorCode(); if (!loadNext()) { renderBanner(); } } function renderBanner() { if (isBanner) { console.log('Outstream: Render Banner'); iinfoOutstreamPosition.innerHTML = ""; iinfoOutstreamPosition.style.height = "330px"; iinfoOutstreamPosition.appendChild(bannerDiv); } else { console.log('Outstream: Banner is not set'); } } function loadNext() { iinfoVastUrlIndex++; if (iinfoVastUrlIndex < iinfoVastUrls.length) { iinfoOutstreamPosition.remove(); outstreamInit(); } else { return false; } adVolume = 1; return true; } /** * Pauses video content and sets up ad UI. */ function onContentPauseRequested() { videoContent.pause(); // This function is where you should setup UI for showing ads (for example, // display ad timer countdown, disable seeking and more.) // setupUIForAds(); } /** * Resumes video content and removes ad UI. */ function onContentResumeRequested() { videoContent.play(); // This function is where you should ensure that your UI is ready // to play content. It is the responsibility of the Publisher to // implement this function when necessary. // setupUIForContent(); } function onActiveView() { if (outstreamContainer) { const containerOffset = outstreamContainer.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight/1 && containerOffset.bottom > 0.0) { if (outstreamPaused) { adsManager.resume(); outstreamPaused = false; } return true; } else { if (!outstreamPaused) { adsManager.pause(); outstreamPaused = true; } } } return false; } let outstreamInitInterval; if (typeof cpexPackage !== "undefined") { outstreamInitInterval = setInterval(tryToInitializeOutstream, 100); } else { const wrapper = getWrapper(); if (wrapper) { let outstreamInitialized = false; window.addEventListener('scroll', () => { if (!outstreamInitialized) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { outstreamInit(); outstreamInitialized = true; } } }); } } function tryToInitializeOutstream() { const wrapper = getWrapper(); if (wrapper) { const containerOffset = wrapper.getBoundingClientRect(); const windowHeight = window.innerHeight; if (containerOffset.top < windowHeight / 1 && containerOffset.bottom > 0.0) { if (cpexPackage.adserver.displayed) { clearInterval(outstreamInitInterval); outstreamInit(); } } } else { clearInterval(outstreamInitInterval); } } }
OSZAR »